1var getRealPath = (pathname = window.location.pathname, desc = false) => { 2 const names = pathname.split("/").filter((name) => { 3 name = name.trim(); 4 return name.length > 0 && name !== "/" && name !== "index.html"; 5 }); 6 if (desc) { 7 return names[0] || "/"; 8 } else { 9 return names[names.length - 1] || "/"; 10 } 11}; 12 13var scrollIntoViewAndWait = (element) => { 14 return new Promise((resolve) => { 15 if ("onscrollend" in window) { 16 document.addEventListener("scrollend", resolve, { once: true }); 17 element.scrollIntoView({ 18 behavior: "smooth", 19 block: "center", 20 inline: "center", 21 }); 22 } else { 23 element.scrollIntoView({ block: "center", inline: "center" }); 24 resolve(); 25 } 26 }); 27}; 28 29// anchor 30_$$( 31 ".article-entry h1>a:first-of-type, .article-entry h2>a:first-of-type, .article-entry h3>a:first-of-type, .article-entry h4>a:first-of-type, .article-entry h5>a:first-of-type, .article-entry h6>a:first-of-type" 32).forEach((element) => { 33 if (window.REIMU_CONFIG.icon_font) { 34 // iconfont 35 element.innerHTML = window.REIMU_CONFIG.anchor_icon 36 ? `&#x${window.REIMU_CONFIG.anchor_icon};` 37 : window.REIMU_CONFIG.anchor_icon === false 38 ? "" 39 : ""; 40 } else { 41 // fontawesome 42 element.innerHTML = window.REIMU_CONFIG.anchor_icon 43 ? `&#x${window.REIMU_CONFIG.anchor_icon};` 44 : window.REIMU_CONFIG.anchor_icon === false 45 ? "" 46 : ""; 47 } 48}); 49 50// lightbox 51_$$(".article-entry img").forEach((element) => { 52 if ( 53 element.parentElement.classList.contains("friend-icon") || 54 element.parentElement.tagName === "A" || 55 element.classList.contains("no-lightbox") 56 ) 57 return; 58 const a = document.createElement("a"); 59 a.href ? (a.href = element.src) : a.setAttribute("href", element.src); 60 if (element.naturalWidth || element.naturalHeight) { 61 a.dataset.pswpWidth = element.naturalWidth; 62 a.dataset.pswpHeight = element.naturalHeight; 63 } else { 64 console.warn( 65 "Image naturalWidth and naturalHeight cannot be obtained right now, fallback to onload." 66 ); 67 element.onload = () => { 68 a.dataset.pswpWidth = element.naturalWidth; 69 a.dataset.pswpHeight = element.naturalHeight; 70 }; 71 } 72 a.target = "_blank"; 73 a.classList.add("article-gallery-item"); 74 element.parentNode.insertBefore(a, element); 75 element.parentNode.removeChild(element); 76 a.appendChild(element); 77}); 78window.lightboxStatus = "ready"; 79window.dispatchEvent(new Event("lightbox:ready")); 80 81// table wrap 82_$$(".article-entry table").forEach((element) => { 83 if (element.closest("figure.highlight")) return; 84 const wrapper = document.createElement("div"); 85 wrapper.classList.add("table-wrapper"); 86 element.parentNode?.insertBefore(wrapper, element); 87 element.parentNode?.removeChild(element); 88 wrapper.appendChild(element); 89}); 90 91// wrap details content for old @reimujs/hexo-renderer-markdown-it-plus 92_$$(".article-entry details.custom-block").forEach((element) => { 93 if (element.querySelector(".detail-content")) return; 94 const summary = element.querySelector("summary"); 95 if (!summary) return; 96 const detailContent = document.createElement("div"); 97 detailContent.classList.add("detail-content"); 98 99 const range = document.createRange(); 100 range.setStartAfter(summary); 101 range.setEndAfter(element.lastChild); 102 detailContent.appendChild(range.extractContents()); 103 104 element.appendChild(detailContent); 105}); 106 107// Mobile nav 108var isMobileNavAnim = false; 109 110_$("#main-nav-toggle") 111 .off("click") 112 .on("click", () => { 113 if (isMobileNavAnim) return; 114 isMobileNavAnim = true; 115 document.body.classList.toggle("mobile-nav-on"); 116 _$("#mask").classList.remove("hide"); 117 setTimeout(() => { 118 isMobileNavAnim = false; 119 }, 300); 120 }); 121 122_$("#mask") 123 ?.off("click") 124 .on("click", () => { 125 if (isMobileNavAnim || !document.body.classList.contains("mobile-nav-on")) 126 return; 127 document.body.classList.remove("mobile-nav-on"); 128 _$("#mask").classList.add("hide"); 129 }); 130 131_$$(".sidebar-toc-btn").forEach((element) => { 132 element.off("click").on("click", function () { 133 if (this.classList.contains("current")) return; 134 _$$(".sidebar-toc-btn").forEach((element) => 135 element.classList.add("current") 136 ); 137 _$$(".sidebar-common-btn").forEach((element) => 138 element.classList.remove("current") 139 ); 140 _$$(".sidebar-toc-sidebar").forEach((element) => 141 element.classList.remove("hidden") 142 ); 143 _$$(".sidebar-common-sidebar").forEach((element) => 144 element.classList.add("hidden") 145 ); 146 }); 147}); 148 149_$$(".sidebar-common-btn").forEach((element) => { 150 element.off("click").on("click", function () { 151 if (this.classList.contains("current")) return; 152 _$$(".sidebar-common-btn").forEach((element) => 153 element.classList.add("current") 154 ); 155 _$$(".sidebar-toc-btn").forEach((element) => 156 element.classList.remove("current") 157 ); 158 _$$(".sidebar-common-sidebar").forEach((element) => 159 element.classList.remove("hidden") 160 ); 161 _$$(".sidebar-toc-sidebar").forEach((element) => 162 element.classList.add("hidden") 163 ); 164 }); 165}); 166 167(() => { 168 const rootRealPath = getRealPath(window.location.pathname); 169 _$$(".sidebar-menu-link-wrap").forEach((link) => { 170 let linkPath = link.querySelector("a").getAttribute("href"); 171 if (linkPath && getRealPath(linkPath) === rootRealPath) { 172 link.classList.add("link-active"); 173 } 174 }); 175})(); 176 177// lazyload 178_$$(".article-entry img").forEach((element) => { 179 if (element.classList.contains("lazyload")) return; 180 element.classList.add("lazyload"); 181 element.setAttribute("data-src", element.src); 182 element.setAttribute("data-sizes", "auto"); 183 element.removeAttribute("src"); 184}); 185 186// to top 187var sidebarTop = _$(".sidebar-top"); 188if (sidebarTop) { 189 sidebarTop.style.transition = "all .3s"; 190 sidebarTop.off("click").on("click", () => { 191 window.scrollTo({ 192 top: 0, 193 behavior: "smooth", 194 }); 195 }); 196 if (document.documentElement.scrollTop < 10) { 197 sidebarTop.style.opacity = 0; 198 } 199} 200 201var __sidebarTopScrollHandler; 202 203if (__sidebarTopScrollHandler) { 204 window.off("scroll", __sidebarTopScrollHandler); 205} 206 207__sidebarTopScrollHandler = () => { 208 const sidebarTop = _$(".sidebar-top"); 209 if (document.documentElement.scrollTop < 10) { 210 sidebarTop.style.opacity = 0; 211 } else { 212 sidebarTop.style.opacity = 1; 213 } 214}; 215 216window.on("scroll", __sidebarTopScrollHandler); 217 218// toc 219_$$("#mobile-nav .toc li").forEach((element) => { 220 element.off("click").on("click", () => { 221 if (isMobileNavAnim || !document.body.classList.contains("mobile-nav-on")) 222 return; 223 document.body.classList.remove("mobile-nav-on"); 224 _$("#mask").classList.add("hide"); 225 }); 226}); 227 228_$$("#mobile-nav .sidebar-menu-link-dummy").forEach((element) => { 229 element.off("click").on("click", () => { 230 if (isMobileNavAnim || !document.body.classList.contains("mobile-nav-on")) 231 return; 232 setTimeout(() => { 233 document.body.classList.remove("mobile-nav-on"); 234 _$("#mask").classList.add("hide"); 235 }, 200); 236 }); 237}); 238 239function tocInit() { 240 if (!_$("#sidebar")) return; 241 const navItems = 242 getComputedStyle(_$("#sidebar")).display === "block" 243 ? _$$("#sidebar .sidebar-toc-wrapper li") 244 : _$$("#mobile-nav .sidebar-toc-wrapper li"); 245 if (!navItems.length) return; 246 247 let activeLock = null; 248 249 const anchorScroll = (event, index) => { 250 event.preventDefault(); 251 const target = document.getElementById( 252 decodeURI(event.currentTarget.getAttribute("href")).slice(1) 253 ); 254 activeLock = index; 255 scrollIntoViewAndWait(target).then(() => { 256 activateNavByIndex(index); 257 activeLock = null; 258 }); 259 }; 260 261 const sections = [...navItems].map((element, index) => { 262 const link = element.querySelector("a.toc-link");
263 link.off("click").on("click", (e) => anchorScroll(e, index)); 264 const anchor = document.getElementById( 265 decodeURI(link.getAttribute("href")).slice(1) 266 ); 267 if (!anchor) return null; 268 const alink = anchor.querySelector("a"); 269 alink?.off("click").on("click", (e) => anchorScroll(e, index)); 270 return anchor; 271 }); 272 273 const activateNavByIndex = (index) => { 274 const target = navItems[index]; 275 276 if (!target || target.classList.contains("current")) return; 277 278 _$$(".sidebar-toc-wrapper .active").forEach((element) => { 279 element.classList.remove("active", "current"); 280 }); 281 282 sections.forEach((element) => { 283 element?.classList.remove("active"); 284 }); 285 286 target.classList.add("active", "current"); 287 sections[index]?.classList.add("active"); 288 289 let parent = target.parentNode; 290 291 while (!parent.matches(".sidebar-toc-sidebar")) { 292 if (parent.matches("li")) { 293 parent.classList.add("active"); 294 const t = document.getElementById( 295 decodeURI( 296 parent.querySelector("a.toc-link").getAttribute("href").slice(1) 297 ) 298 ); 299 if (t) { 300 t.classList.add("active"); 301 } 302 } 303 parent = parent.parentNode; 304 } 305 // Scrolling to center active TOC element if TOC content is taller than viewport. 306 if (!_$(".sidebar-toc-sidebar").classList.contains("hidden")) { 307 const tocWrapper = _$(".sidebar-toc-wrapper"); 308 tocWrapper.scrollTo({ 309 top: 310 tocWrapper.scrollTop + target.offsetTop - tocWrapper.offsetHeight / 2, 311 behavior: "smooth", 312 }); 313 } 314 }; 315 316 const findIndex = (entries) => { 317 let index = 0; 318 let entry = entries[index]; 319 320 if (entry.boundingClientRect.top > 0) { 321 index = sections.indexOf(entry.target); 322 return index === 0 ? 0 : index - 1; 323 } 324 for (; index < entries.length; index++) { 325 if (entries[index].boundingClientRect.top <= 0) { 326 entry = entries[index]; 327 } else { 328 return sections.indexOf(entry.target); 329 } 330 } 331 return sections.indexOf(entry.target); 332 }; 333 334 const observer = new IntersectionObserver( 335 (entries) => { 336 const index = findIndex(entries) + (window.diffY > 0 ? 1 : 0); 337 if (activeLock === null) { 338 activateNavByIndex(index); 339 } 340 }, 341 { 342 rootMargin: "0px 0px -100% 0px", 343 threshold: 0, 344 } 345 ); 346 347 sections.forEach((element) => { 348 element && observer.observe(element); 349 }); 350} 351 352// hexo-blog-encrypt 353window 354 .off("hexo-blog-decrypt") 355 .on("hexo-blog-decrypt", tocInit) 356 .on("hexo-blog-decrypt", () => { 357 const script = document.createElement("script"); 358 script.src = "/js/insert_highlight.js"; 359 script.setAttribute("data-pjax", true); 360 document.body.appendChild(script); 361 }); 362tocInit(); 363 364_$(".sponsor-button") 365 ?.off("click") 366 .on("click", () => { 367 _$(".sponsor-button")?.classList.toggle("active"); 368 _$(".sponsor-tip")?.classList.toggle("active"); 369 _$(".sponsor-qr")?.classList.toggle("active"); 370 }); 371 372var shareWeixinHandler; 373if (shareWeixinHandler) { 374 document.off("click", shareWeixinHandler); 375} 376shareWeixinHandler = (e) => { 377 if (e.target.closest(".share-icon.icon-weixin")) return; 378 const sw = _$("#share-weixin"); 379 if (sw && sw.classList.contains("active")) { 380 sw.classList.remove("active"); 381 sw.addEventListener( 382 "transitionend", 383 function handler() { 384 sw.style.display = "none"; 385 sw.removeEventListener("transitionend", handler); 386 }, 387 { once: true }, 388 ); 389 } 390}; 391document.on("click", shareWeixinHandler); 392 393_$(".share-icon.icon-weixin") 394 ?.off("click") 395 .on("click", function (e) { 396 const iconPosition = this.getBoundingClientRect(); 397 const shareWeixin = this.querySelector("#share-weixin"); 398 399 if (iconPosition.x - 148 < 0) { 400 shareWeixin.style.left = `-${iconPosition.x - 10}px`; 401 } else if (iconPosition.x + 172 > window.innerWidth) { 402 shareWeixin.style.left = `-${310 - window.innerWidth + iconPosition.x}px`; 403 } else { 404 shareWeixin.style.left = "-138px"; 405 } 406 if (e.target === this) { 407 const el = shareWeixin; 408 if (!el) return; 409 if (!el.classList.contains("active")) { 410 el.style.display = "block"; 411 requestAnimationFrame(() => { 412 el.classList.add("active"); 413 }); 414 } else { 415 el.classList.remove("active"); 416 const onEnd = (ev) => { 417 if (ev.propertyName === "opacity") { 418 el.style.display = "none"; 419 el.removeEventListener("transitionend", onEnd); 420 } 421 }; 422 el.addEventListener("transitionend", onEnd); 423 } 424 } 425 // if contains img return 426 if (_$(".share-weixin-canvas").children.length) { 427 return; 428 } 429 const { cover, excerpt, description, title, stripContent, author } = 430 window.REIMU_POST; 431 _$("#share-weixin-banner").src = cover; 432 _$("#share-weixin-title").innerText = title; 433 _$("#share-weixin-desc").innerText = excerpt || description || str
433ipContent; 434 _$("#share-weixin-author").innerText = "By: " + author; 435 QRCode.toDataURL(window.REIMU_POST.url, function (error, dataUrl) { 436 if (error) { 437 console.error(error); 438 return; 439 } 440 _$("#share-weixin-qr").src = dataUrl; 441 snapdom 442 .toPng(_$(".share-weixin-dom")) 443 .then((img) => { 444 _$(".share-weixin-canvas").appendChild(img); 445 }) 446 .catch(() => { 447 // we assume that the error is caused by the browser's security policy 448 // so we will remove the banner and try again 449 _$("#share-weixin-banner").remove(); 450 snapdom 451 .toPng(_$(".share-weixin-dom")) 452 .then((img) => { 453 _$(".share-weixin-canvas").appendChild(img); 454 }) 455 .catch(() => { 456 console.error("Failed to generate weixin share image."); 457 }); 458 }); 459 }); 460 }); 461 462var imgElement = _$("#header > img"); 463if (imgElement.src || imgElement.style.background) { 464 window.bannerElement = imgElement; 465} else { 466 window.bannerElement = _$("#header > picture img"); 467} 468 469window.generateSchemeHandler?.();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.