summaryrefslogtreecommitdiff
path: root/_shared/docs.js
blob: 7e0731040b198748f668ff7e52b3bf4def776d80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* panto docs — progressive enhancement only.
   The site is fully functional with this file absent or JS disabled:
   every nav item is a real link, all content is in the HTML. This adds
   the mobile sidebar toggle, code copy buttons, and TOC scroll-spy. */
(function () {
  'use strict';

  /* ---- Mobile sidebar toggle ---------------------------------------- */
  var menuBtn = document.querySelector('[data-menu-toggle]');
  var sidebar = document.querySelector('.pd-sidebar');
  var scrim = document.querySelector('.pd-scrim');
  function closeMenu() {
    if (sidebar) sidebar.classList.remove('pd-sidebar--open');
  }
  if (menuBtn && sidebar) {
    menuBtn.addEventListener('click', function () {
      sidebar.classList.toggle('pd-sidebar--open');
    });
  }
  if (scrim) scrim.addEventListener('click', closeMenu);
  if (sidebar) {
    sidebar.addEventListener('click', function (e) {
      if (e.target.closest('a')) closeMenu();
    });
  }

  /* ---- Code copy buttons -------------------------------------------- */
  document.querySelectorAll('.pg-code__copy').forEach(function (btn) {
    btn.addEventListener('click', function () {
      var block = btn.closest('.pg-code');
      var pre = block && block.querySelector('pre');
      if (!pre) return;
      var text = pre.innerText;
      var done = function () {
        btn.classList.add('pg-code__copy--done');
        var label = btn.querySelector('.pg-code__label');
        if (label) label.textContent = 'Copied';
        setTimeout(function () {
          btn.classList.remove('pg-code__copy--done');
          if (label) label.textContent = 'Copy';
        }, 1400);
      };
      if (navigator.clipboard) navigator.clipboard.writeText(text).then(done, done);
      else done();
    });
  });

  /* ---- Scroll-spy: highlight the active section in TOC + sidebar ---- */
  var tocLinks = Array.prototype.slice.call(document.querySelectorAll('.pd-toc__link'));
  var sideLinks = Array.prototype.slice.call(
    document.querySelectorAll('.pd-navsec--current .pd-navsec__link')
  );
  if (!tocLinks.length || !('IntersectionObserver' in window)) return;

  var ids = tocLinks.map(function (a) {
    var href = a.getAttribute('href') || '';
    return href.charAt(0) === '#' ? href.slice(1) : href.split('#')[1];
  }).filter(Boolean);

  function setActive(id) {
    tocLinks.forEach(function (a) {
      var h = a.getAttribute('href') || '';
      a.classList.toggle('pd-toc__link--active', h === '#' + id);
    });
    sideLinks.forEach(function (a) {
      var h = a.getAttribute('href') || '';
      a.classList.toggle('pd-navsec__link--active', h.split('#')[1] === id);
    });
  }

  var visible = new Set();
  var obs = new IntersectionObserver(function (entries) {
    entries.forEach(function (e) {
      if (e.isIntersecting) visible.add(e.target.id);
      else visible.delete(e.target.id);
    });
    var first = ids.find(function (id) { return visible.has(id); });
    if (first) setActive(first);
  }, { rootMargin: '-72px 0px -68% 0px', threshold: 0 });

  ids.forEach(function (id) {
    var el = document.getElementById(id);
    if (el) obs.observe(el);
  });
})();