123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- //= require ../lib/_jquery
- //= require ../lib/_imagesloaded.min
- ;(function () {
- 'use strict';
- var htmlPattern = /<[^>]*>/g;
- var loaded = false;
- var debounce = function(func, waitTime) {
- var timeout = false;
- return function() {
- if (timeout === false) {
- setTimeout(function() {
- func();
- timeout = false;
- }, waitTime);
- timeout = true;
- }
- };
- };
- var closeToc = function() {
- $(".toc-wrapper").removeClass('open');
- $("#nav-button").removeClass('open');
- };
- function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) {
- var headerHeights = {};
- var pageHeight = 0;
- var windowHeight = 0;
- var originalTitle = document.title;
- var recacheHeights = function() {
- headerHeights = {};
- pageHeight = $(document).height();
- windowHeight = $(window).height();
- $toc.find(tocLinkSelector).each(function() {
- var targetId = $(this).attr('href');
- if (targetId[0] === "#") {
- headerHeights[targetId] = $("#" + $.escapeSelector(targetId.substring(1))).offset().top;
- }
- });
- };
- var refreshToc = function() {
- var currentTop = $(document).scrollTop() + scrollOffset;
- if (currentTop + windowHeight >= pageHeight) {
- // at bottom of page, so just select last header by making currentTop very large
- // this fixes the problem where the last header won't ever show as active if its content
- // is shorter than the window height
- currentTop = pageHeight + 1000;
- }
- var best = null;
- for (var name in headerHeights) {
- if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) {
- best = name;
- }
- }
- // Catch the initial load case
- if (currentTop == scrollOffset && !loaded) {
- best = window.location.hash;
- loaded = true;
- }
- var $best = $toc.find("[href='" + best + "']").first();
- if (!$best.hasClass("active")) {
- // .active is applied to the ToC link we're currently on, and its parent <ul>s selected by tocListSelector
- // .active-expanded is applied to the ToC links that are parents of this one
- $toc.find(".active").removeClass("active");
- $toc.find(".active-parent").removeClass("active-parent");
- $best.addClass("active");
- $best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent');
- $best.siblings(tocListSelector).addClass("active");
- $toc.find(tocListSelector).filter(":not(.active)").slideUp(150);
- $toc.find(tocListSelector).filter(".active").slideDown(150);
- if (window.history.replaceState) {
- window.history.replaceState(null, "", best);
- }
- var thisTitle = $best.data("title");
- if (thisTitle !== undefined && thisTitle.length > 0) {
- document.title = thisTitle.replace(htmlPattern, "") + " – " + originalTitle;
- } else {
- document.title = originalTitle;
- }
- }
- };
- var makeToc = function() {
- recacheHeights();
- refreshToc();
- $("#nav-button").click(function() {
- $(".toc-wrapper").toggleClass('open');
- $("#nav-button").toggleClass('open');
- return false;
- });
- $(".page-wrapper").click(closeToc);
- $(".toc-link").click(closeToc);
- // reload immediately after scrolling on toc click
- $toc.find(tocLinkSelector).click(function() {
- setTimeout(function() {
- refreshToc();
- }, 0);
- });
- $(window).scroll(debounce(refreshToc, 200));
- $(window).resize(debounce(recacheHeights, 200));
- };
- makeToc();
- window.recacheHeights = recacheHeights;
- window.refreshToc = refreshToc;
- }
- window.loadToc = loadToc;
- })();
|