Skip to content
quarry Artifact [a2bf43acc1]
Login

Artifact [a2bf43acc1]

Artifact a2bf43acc15c69205ba8638cddd6e967f6a4d143402f9ca022e8fa130c8277bd:


// wiki.js marks which section of a long page you are currently reading
// in the contents rail. Everything works without it: the rail is plain
// anchor links to ids the server already wrote into the document, and
// this only says WHERE YOU ARE — the one thing a static link cannot.
//
// Wikipedia's Vector 2022 found readers consult a contents repeatedly
// while reading, and that a rail which tracks the page increases how
// much of it they explore. Fossil's own Cookbook — 51 headings, 26,000
// pixels — is exactly the page that finding is about.
(function () {
  "use strict";

  var toc = document.querySelector(".w-toc");
  if (!toc) { return; }

  var links = Array.prototype.slice.call(toc.querySelectorAll("a[href^='#']"));
  var targets = links.map(function (a) {
    try {
      return document.getElementById(decodeURIComponent(a.hash.slice(1)));
    } catch (e) {
      return null;   // a hash this browser will not decode is not a target
    }
  });
  if (!links.length) { return; }

  var current = -1;
  function mark() {
    // The section in view is the last one whose heading has passed the
    // top of the viewport. Reading the top edge rather than the middle
    // means a heading clicked in the rail lands on itself.
    var found = 0;
    for (var i = 0; i < targets.length; i++) {
      if (targets[i] && targets[i].getBoundingClientRect().top < 80) { found = i; }
    }
    if (found === current) { return; }   // don't touch the DOM to say nothing
    if (current >= 0) { links[current].classList.remove("here"); }
    links[found].classList.add("here");
    current = found;
  }

  var queued = false;
  function onScroll() {
    if (queued) { return; }
    queued = true;
    requestAnimationFrame(function () { queued = false; mark(); });
  }

  addEventListener("scroll", onScroll, { passive: true });
  addEventListener("resize", onScroll, { passive: true });
  mark();
}());