|
| 1 | +function search() { |
| 2 | + box = document.getElementById('search-box'); |
| 3 | + list = document.getElementById('search-results'); |
| 4 | + list.innerHTML = ''; |
| 5 | + |
| 6 | + if (box.value == "") { |
| 7 | + return |
| 8 | + } |
| 9 | + |
| 10 | + config = { |
| 11 | + fields: { |
| 12 | + title: { |
| 13 | + boost: 2, |
| 14 | + }, |
| 15 | + body: { |
| 16 | + boost: 1 |
| 17 | + } |
| 18 | + }, |
| 19 | + bool: "OR", |
| 20 | + expand: true |
| 21 | + } |
| 22 | + |
| 23 | + INDEX.search(box.value, config).forEach(function (result) { |
| 24 | + listItem = document.createElement("li"); |
| 25 | + listItem.className = "search-result-item"; |
| 26 | + listItem.innerHTML = |
| 27 | + "<a href='" + result.doc.uri + "'>" + result.doc.title + |
| 28 | + "<p class='search-result-item-preview'>" + searchPreview(result.doc.body) + "</p>" + |
| 29 | + "</a>"; |
| 30 | + |
| 31 | + list.appendChild(listItem); |
| 32 | + }); |
| 33 | +} |
| 34 | + |
| 35 | +function searchPreview(body) { |
| 36 | + return body.substring(0, 100) |
| 37 | + .replace(/=+/g, "") |
| 38 | + .replace(/#+/g, "") |
| 39 | + .replace(/\*+/g, "") |
| 40 | + .replace(/_+/g, "") + |
| 41 | + "..."; |
| 42 | +} |
| 43 | + |
| 44 | +function disableScrollifMenuOpen() { |
| 45 | + var checkbox = document.getElementById('menu-toggle-switch'); |
| 46 | + |
| 47 | + if (checkbox.checked) { |
| 48 | + document.body.style.overflow = 'hidden'; |
| 49 | + } else { |
| 50 | + document.body.style.overflow = 'auto'; |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +function atTop() { |
| 55 | + var nav = document.getElementsByClassName("sidebar-right")[0]; |
| 56 | + |
| 57 | + return window.scrollY <= nav.offsetTop + 50; |
| 58 | +} |
| 59 | + |
| 60 | +function navTouchingBottom() { |
| 61 | + var nav = document.getElementsByClassName("page-nav")[0]; |
| 62 | + |
| 63 | + var height = Math.max( |
| 64 | + document.body.scrollHeight, document.documentElement.scrollHeight, |
| 65 | + document.body.offsetHeight, document.documentElement.offsetHeight, |
| 66 | + document.body.clientHeight, document.documentElement.clientHeight |
| 67 | + ); |
| 68 | + // Magic number determined |
| 69 | + // by height of bottom wave |
| 70 | + return window.scrollY + nav.offsetTop + nav.offsetHeight >= height - 230; |
| 71 | +} |
| 72 | + |
| 73 | +function scrolledUp() { |
| 74 | + var height = Math.max( |
| 75 | + document.body.scrollHeight, document.documentElement.scrollHeight, |
| 76 | + document.body.offsetHeight, document.documentElement.offsetHeight, |
| 77 | + document.body.clientHeight, document.documentElement.clientHeight |
| 78 | + ); |
| 79 | + |
| 80 | + // Magic number determined |
| 81 | + // by height of bottom wave |
| 82 | + return window.scrollY + window.innerHeight < height - 230; |
| 83 | +} |
| 84 | + |
| 85 | +function dragRightMenu() { |
| 86 | + if (atTop()) { |
| 87 | + document.getElementById('page-nav').classList.remove('fixed'); |
| 88 | + document.getElementsByClassName('sidebar-right')[0].classList.remove('bottom'); |
| 89 | + } else if (scrolledUp()) { |
| 90 | + document.getElementById('page-nav').classList.add('fixed'); |
| 91 | + document.getElementsByClassName('sidebar-right')[0].classList.remove('bottom'); |
| 92 | + } else if (navTouchingBottom()) { |
| 93 | + document.getElementById('page-nav').classList.remove('fixed'); |
| 94 | + document.getElementsByClassName('sidebar-right')[0].classList.add('bottom'); |
| 95 | + } else { |
| 96 | + document.getElementById('page-nav').classList.add('fixed'); |
| 97 | + document.getElementsByClassName('sidebar-right')[0].classList.remove('bottom'); |
| 98 | + } |
| 99 | +} |
| 100 | + |
| 101 | +function isVisible(element) { |
| 102 | + var rect = element.getBoundingClientRect(); |
| 103 | + var elemTop = rect.top; |
| 104 | + var elemBottom = rect.bottom; |
| 105 | + |
| 106 | + var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight); |
| 107 | + return isVisible; |
| 108 | +} |
| 109 | + |
| 110 | +function toggleColor() { |
| 111 | + var color = localStorage.getItem('doctave-color') |
| 112 | + |
| 113 | + if (color === 'dark') { |
| 114 | + localStorage.setItem('doctave-color', 'light'); |
| 115 | + } else { |
| 116 | + localStorage.setItem('doctave-color', 'dark'); |
| 117 | + } |
| 118 | + |
| 119 | + setColor(); |
| 120 | +} |
| 121 | + |
| 122 | +function setColor() { |
| 123 | + var color = localStorage.getItem('doctave-color') |
| 124 | + |
| 125 | + if (color === 'dark') { |
| 126 | + document.querySelector("link[rel='stylesheet'][href*='prism-']").href = BASE_PATH + "assets/prism-atom-dark.css?v=" + DOCTAVE_TIMESTAMP; |
| 127 | + document.getElementsByTagName('html')[0].classList.remove('light'); |
| 128 | + document.getElementsByTagName('html')[0].classList.add('dark'); |
| 129 | + } else { |
| 130 | + document.querySelector("link[rel='stylesheet'][href*='prism-']").href = BASE_PATH + "assets/prism-ghcolors.css?" + DOCTAVE_TIMESTAMP; |
| 131 | + document.getElementsByTagName('html')[0].classList.remove('dark'); |
| 132 | + document.getElementsByTagName('html')[0].classList.add('light'); |
| 133 | + } |
| 134 | +} |
| 135 | + |
| 136 | +document.getElementById("light-dark-mode-switch").addEventListener("click", toggleColor); |
| 137 | + |
| 138 | + |
| 139 | +// Initialize mermaid.js based on color theme |
| 140 | +var color = localStorage.getItem('doctave-color') |
| 141 | +if (color === 'dark') { |
| 142 | + console.log("DARK MODE"); |
| 143 | + mermaid.initialize({ 'theme': 'dark' }); |
| 144 | +} else { |
| 145 | + mermaid.initialize({ 'theme': 'default' }); |
| 146 | +} |
| 147 | + |
| 148 | +// Setup Katex |
| 149 | +var mathElements = document.getElementsByClassName("math"); |
| 150 | + |
| 151 | +const macros = {} |
| 152 | + |
| 153 | +for (let element of mathElements) { |
| 154 | + let latex = element.textContent; |
| 155 | + |
| 156 | + try { |
| 157 | + katex.render(latex, element, { |
| 158 | + displayMode: true, |
| 159 | + macros: macros, |
| 160 | + }); |
| 161 | + } catch (e) { |
| 162 | + if (e instanceof katex.ParseError) { |
| 163 | + // KaTeX can't parse the expression |
| 164 | + var error_message = e.message |
| 165 | + .replaceAll(/^KaTeX parse error: /g, "Error parsing math notation:\n") |
| 166 | + .replaceAll(/&/g, "&") |
| 167 | + .replaceAll(/</g, "<") |
| 168 | + .replaceAll(/>/g, ">") |
| 169 | + .replaceAll("\n", "<br />"); |
| 170 | + |
| 171 | + element.innerHTML = "<p class='katex-error-msg'>" + error_message + "</p>" + latex.trim().replaceAll("\n", "<br />"); |
| 172 | + element.classList.add("katex-error"); |
| 173 | + } else { |
| 174 | + throw e; // other error |
| 175 | + } |
| 176 | + } |
| 177 | +} |
| 178 | + |
| 179 | +// Setup Prism |
| 180 | +Prism.plugins.autoloader.languages_path = BASE_PATH + 'assets/prism-grammars/'; |
| 181 | + |
| 182 | + |
| 183 | +// Load search index |
| 184 | +var INDEX; |
| 185 | + |
| 186 | +fetch(BASE_PATH + 'search_index.json') |
| 187 | + .then(function (response) { |
| 188 | + if (!response.ok) { |
| 189 | + throw new Error("HTTP error " + response.status); |
| 190 | + } |
| 191 | + return response.json(); |
| 192 | + }) |
| 193 | + .then(function (json) { |
| 194 | + INDEX = elasticlunr.Index.load(json) |
| 195 | + document.getElementById('search-box').oninput = search; |
| 196 | + search(); |
| 197 | + }); |
| 198 | + |
| 199 | +// Setup keyboard shortcuts |
| 200 | +document.onkeydown = function (e) { |
| 201 | + var searchResults = document.getElementById('search-results'); |
| 202 | + var first = searchResults.firstChild; |
| 203 | + var searchBox = document.getElementById('search-box'); |
| 204 | + |
| 205 | + switch (e.keyCode) { |
| 206 | + case 83: // The S key |
| 207 | + if (document.activeElement == searchBox) { |
| 208 | + break; |
| 209 | + } else { |
| 210 | + searchBox.focus(); |
| 211 | + e.preventDefault(); |
| 212 | + } |
| 213 | + break; |
| 214 | + case 38: // if the UP key is pressed |
| 215 | + if (document.activeElement == (searchBox || first)) { |
| 216 | + break; |
| 217 | + } else { |
| 218 | + document.activeElement.parentNode.previousSibling.firstChild.focus(); |
| 219 | + e.preventDefault(); |
| 220 | + } |
| 221 | + break; |
| 222 | + case 40: // if the DOWN key is pressed |
| 223 | + if (document.activeElement == searchBox) { |
| 224 | + first.firstChild.focus(); |
| 225 | + e.preventDefault(); |
| 226 | + } else { |
| 227 | + document.activeElement.parentNode.nextSibling.firstChild.focus(); |
| 228 | + e.preventDefault(); |
| 229 | + } |
| 230 | + break; |
| 231 | + case 27: // if the ESC key is pressed |
| 232 | + if (first) { |
| 233 | + searchResults.innerHTML = ''; |
| 234 | + } |
| 235 | + break; |
| 236 | + } |
| 237 | +} |
| 238 | + |
| 239 | +disableScrollifMenuOpen(); |
| 240 | +dragRightMenu(); |
| 241 | +setColor(); |
0 commit comments