File size: 3,386 Bytes
0cb18d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use strict";
const tabs = [...document.querySelectorAll('[role="tab"]')];
function selectTab(tab) {
  tabs.forEach(item => {
    const selected = item === tab;
    item.setAttribute("aria-selected", String(selected));
    item.tabIndex = selected ? 0 : -1;
    document.getElementById(item.getAttribute("aria-controls")).hidden = !selected;
  });
  if (tab.id === "pdf-tab") {
    const viewer = document.getElementById("pdf-viewer");
    if (!viewer.hasAttribute("src")) viewer.src = viewer.dataset.src;
  }
}
tabs.forEach((tab, index) => {
  tab.addEventListener("click", () => selectTab(tab));
  tab.addEventListener("keydown", event => {
    if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return;
    event.preventDefault();
    const next = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs.at(-1) : tabs[(index + (event.key === "ArrowRight" ? 1 : -1) + tabs.length) % tabs.length];
    selectTab(next); next.focus();
  });
});
const search = document.getElementById("search");
const status = document.getElementById("search-status");
const clear = document.getElementById("clear-search");
const sections = [...document.querySelectorAll(".paper-section")];
const links = [...document.querySelectorAll(".contents nav a")];
const original = new Map(sections.map(section => [section, section.innerHTML]));
const plain = new Map(sections.map(section => [section, section.textContent.toLocaleLowerCase()]));
function filterSections() {
  const query = search.value.trim().toLocaleLowerCase();
  let count = 0;
  sections.forEach(section => {
    section.innerHTML = original.get(section);
    const matches = !query || plain.get(section).includes(query);
    section.hidden = !matches;
    const link = links.find(item => item.getAttribute("href") === `#${section.id}`);
    if (link) link.hidden = !matches;
    if (!matches) return;
    count++;
    if (!query) return;
    const walker = document.createTreeWalker(section, NodeFilter.SHOW_TEXT);
    const nodes = [];
    while (walker.nextNode()) nodes.push(walker.currentNode);
    nodes.forEach(node => {
      const value = node.textContent;
      const lower = value.toLocaleLowerCase();
      let start = 0, position = lower.indexOf(query);
      if (position < 0) return;
      const fragment = document.createDocumentFragment();
      while (position >= 0) {
        fragment.append(document.createTextNode(value.slice(start, position)));
        const mark = document.createElement("mark");
        mark.textContent = value.slice(position, position + query.length);
        fragment.append(mark);
        start = position + query.length;
        position = lower.indexOf(query, start);
      }
      fragment.append(document.createTextNode(value.slice(start)));
      node.replaceWith(fragment);
    });
  });
  status.textContent = query ? `${count} of ${sections.length} sections match` : `${sections.length} sections`;
  clear.hidden = !query;
  document.getElementById("no-results").hidden = count > 0;
}
search.addEventListener("input", filterSections);
clear.addEventListener("click", () => { search.value = ""; filterSections(); search.focus(); });
links.forEach(link => link.addEventListener("click", () => {
  links.forEach(item => item.classList.toggle("active", item === link));
}));
document.querySelector('.provenance-link').addEventListener('click', () => selectTab(tabs[0]));