github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/shyft_documentation/source/javascripts/app/_toc.js (about)

     1  //= require ../lib/_jquery
     2  //= require ../lib/_imagesloaded.min
     3  ;(function () {
     4    'use strict';
     5  
     6    var loaded = false;
     7  
     8    var debounce = function(func, waitTime) {
     9      var timeout = false;
    10      return function() {
    11        if (timeout === false) {
    12          setTimeout(function() {
    13            func();
    14            timeout = false;
    15          }, waitTime);
    16          timeout = true;
    17        }
    18      };
    19    };
    20  
    21    var closeToc = function() {
    22      $(".toc-wrapper").removeClass('open');
    23      $("#nav-button").removeClass('open');
    24    };
    25  
    26    function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) {
    27      var headerHeights = {};
    28      var pageHeight = 0;
    29      var windowHeight = 0;
    30      var originalTitle = document.title;
    31  
    32      var recacheHeights = function() {
    33        headerHeights = {};
    34        pageHeight = $(document).height();
    35        windowHeight = $(window).height();
    36  
    37        $toc.find(tocLinkSelector).each(function() {
    38          var targetId = $(this).attr('href');
    39          if (targetId[0] === "#") {
    40            headerHeights[targetId] = $(targetId).offset().top;
    41          }
    42        });
    43      };
    44  
    45      var refreshToc = function() {
    46        var currentTop = $(document).scrollTop() + scrollOffset;
    47  
    48        if (currentTop + windowHeight >= pageHeight) {
    49          // at bottom of page, so just select last header by making currentTop very large
    50          // this fixes the problem where the last header won't ever show as active if its content
    51          // is shorter than the window height
    52          currentTop = pageHeight + 1000;
    53        }
    54  
    55        var best = null;
    56        for (var name in headerHeights) {
    57          if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) {
    58            best = name;
    59          }
    60        }
    61  
    62        // Catch the initial load case
    63        if (currentTop == scrollOffset && !loaded) {
    64          best = window.location.hash;
    65          loaded = true;
    66        }
    67  
    68        var $best = $toc.find("[href='" + best + "']").first();
    69        if (!$best.hasClass("active")) {
    70          // .active is applied to the ToC link we're currently on, and its parent <ul>s selected by tocListSelector
    71          // .active-expanded is applied to the ToC links that are parents of this one
    72          $toc.find(".active").removeClass("active");
    73          $toc.find(".active-parent").removeClass("active-parent");
    74          $best.addClass("active");
    75          $best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent');
    76          $best.siblings(tocListSelector).addClass("active");
    77          $toc.find(tocListSelector).filter(":not(.active)").slideUp(150);
    78          $toc.find(tocListSelector).filter(".active").slideDown(150);
    79          // TODO remove classnames
    80          document.title = $best.data("title") + " – " + originalTitle;
    81        }
    82      };
    83  
    84      var makeToc = function() {
    85        recacheHeights();
    86        refreshToc();
    87  
    88        $("#nav-button").click(function() {
    89          $(".toc-wrapper").toggleClass('open');
    90          $("#nav-button").toggleClass('open');
    91          return false;
    92        });
    93        $(".page-wrapper").click(closeToc);
    94        $(".toc-link").click(closeToc);
    95  
    96        // reload immediately after scrolling on toc click
    97        $toc.find(tocLinkSelector).click(function() {
    98          setTimeout(function() {
    99            refreshToc();
   100          }, 0);
   101        });
   102  
   103        $(window).scroll(debounce(refreshToc, 200));
   104        $(window).resize(debounce(recacheHeights, 200));
   105      };
   106  
   107      makeToc();
   108  
   109      window.recacheHeights = recacheHeights;
   110      window.refreshToc = refreshToc;
   111    }
   112  
   113    window.loadToc = loadToc;
   114  })();