renderFootnotes = function () { const removeEl = (el) => { if (!el) return; el.remove ? el.remove() : el.parentNode.removeChild(el); }; const insertAfter = (target, sib) => { target.after ? target.after(sib) : ( target.parentNode.insertBefore(sib, target.nextSibling) ); }; const insideOut = (el) => { var p = el.parentNode, x = el.innerHTML, c = document.createElement('div'); // a tmp container insertAfter(p, c); c.appendChild(el); el.innerHTML = ''; el.appendChild(p); p.innerHTML = x; // let the original parent have the content of its child insertAfter(c, c.firstElementChild); removeEl(c); }; document.querySelectorAll('.footnotes > ol > li[id^="fn"], #refs > div[id^="ref-"]').forEach(function (fn) { a = document.querySelectorAll('a[href="#' + fn.id + '"]'); if (a.length === 0) return; a.forEach(function (el) { el.removeAttribute('href') }); a = a[0]; side = document.createElement('div'); side.className = 'side side-right'; if (/^fn/.test(fn.id)) { side.innerHTML = fn.innerHTML; var number = a.innerText; // footnote number side.firstElementChild.innerHTML = '' + number + ' ' + side.firstElementChild.innerHTML; removeEl(side.querySelector('a[href^="#fnref"]')); // remove backreference a.parentNode.tagName === 'SUP' && insideOut(a); } else { side.innerHTML = fn.outerHTML; a = a.parentNode; } insertAfter(a, side); a.classList.add('note-ref'); removeEl(fn); }) document.querySelectorAll('.footnotes, #refs').forEach(function (fn) { var items = fn.children; if (fn.id === 'refs') return items.length === 0 && removeEl(fn); // there must be a
and an
    left if (items.length !== 2 || items[0].tagName !== 'HR' || items[1].tagName !== 'OL') return; items[1].childElementCount === 0 && removeEl(fn); }); }(); renderAnchor = function () { for (let num = 1; num <= 6; num++) { // search h1-h6 const headers = document.querySelectorAll('.article-post>h' + num); for (let i = 0; i < headers.length; i++) { const header = headers[i]; // add anchor before h1-h6 header.innerHTML = `${header.innerHTML}`; } } }(); switchDarkMode = function () { const rootElement = document.documentElement; // const darkModeStorageKey = 'user-color-scheme'; // use as localStorage's key const rootElementDarkModeAttributeName = 'data-user-color-scheme'; const darkModeTogglebuttonElement = document.getElementById('dark-mode-button'); const setLS = (k, v) => { try { localStorage.setItem(k, v); } catch (e) { } } const removeLS = (k) => { try { localStorage.removeItem(k); } catch (e) { } } const getLS = (k) => { try { return localStorage.getItem(k); } catch (e) { return null // the same as localStorage.getItem() get nothing } } const getModeFromCSSMediaQuery = () => { // use matchMedia API return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' } const resetRootDarkModeAttributeAndLS = () => { rootElement.removeAttribute(rootElementDarkModeAttributeName); removeLS(darkModeStorageKey); } const validColorModeKeys = { 'dark': true, 'light': true } const modeIcons = { 'dark': '☀️', 'light': '🌙' } const setModeButtonIcon = (mode) => { darkModeTogglebuttonElement.innerHTML = modeIcons[mode] } const applyCustomDarkModeSettings = (mode) => { // receive user's operation or get previous mode from localStorage const currentSetting = mode || getLS(darkModeStorageKey); if (currentSetting === getModeFromCSSMediaQuery()) { // When the user selected mode equal prefers-color-scheme // reset and restored to automatic mode nowMode = getModeFromCSSMediaQuery() resetRootDarkModeAttributeAndLS(); } else if (validColorModeKeys[currentSetting]) { nowMode = currentSetting rootElement.setAttribute(rootElementDarkModeAttributeName, currentSetting); } else { // 首次访问或从未使用过开关、localStorage 中没有存储的值,currentSetting 是 null // 或者 localStorage 被篡改,currentSetting 不是合法值 nowMode = getModeFromCSSMediaQuery() resetRootDarkModeAttributeAndLS(); } setModeButtonIcon(nowMode) } const invertDarkModeObj = { 'dark': 'light', 'light': 'dark' } const toggleCustomDarkMode = () => { let currentSetting = getLS(darkModeStorageKey); if (validColorModeKeys[currentSetting]) { // get mode from localStorage and set the opposite currentSetting = invertDarkModeObj[currentSetting]; } else if (currentSetting === null) { // if get null from localStorage // get mode from prefers-color-scheme and set the opposite currentSetting = invertDarkModeObj[getModeFromCSSMediaQuery()]; } else { // get anything error, return return; } // set opposite mode into localStorage setLS(darkModeStorageKey, currentSetting); return currentSetting; } // when page loaded set page mode applyCustomDarkModeSettings(); darkModeTogglebuttonElement.addEventListener('click', () => { // handle user click switch dark mode button applyCustomDarkModeSettings(toggleCustomDarkMode()); }) }();