New site
This commit is contained in:
47
public/js/codecopy.js
Normal file
47
public/js/codecopy.js
Normal file
@@ -0,0 +1,47 @@
|
||||
(() => {
|
||||
// <stdin>
|
||||
var copyText = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M288 448L64 448l0-224 64 0 0-64-64 0c-35.3 0-64 28.7-64 64L0 448c0 35.3 28.7 64 64 64l224 0c35.3 0 64-28.7 64-64l0-64-64 0 0 64zm-64-96l224 0c35.3 0 64-28.7 64-64l0-224c0-35.3-28.7-64-64-64L224 0c-35.3 0-64 28.7-64 64l0 224c0 35.3 28.7 64 64 64z"/></svg>';
|
||||
var copiedText = 'Copied! <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zM337 209L209 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L303 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg>';
|
||||
function createCopyButton(codeblock) {
|
||||
const container = codeblock.parentNode.parentNode;
|
||||
const copybutton = document.createElement("button");
|
||||
copybutton.classList.add("copy-button");
|
||||
copybutton.innerHTML = copyText;
|
||||
function copyingDone() {
|
||||
copybutton.innerHTML = copiedText;
|
||||
setTimeout(() => {
|
||||
copybutton.innerHTML = copyText;
|
||||
}, 500);
|
||||
}
|
||||
copybutton.addEventListener("click", (cb) => {
|
||||
if ("clipboard" in navigator) {
|
||||
navigator.clipboard.writeText(codeblock.textContent);
|
||||
copyingDone();
|
||||
return;
|
||||
}
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(codeblock);
|
||||
const selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
try {
|
||||
document.execCommand("copy");
|
||||
copyingDone();
|
||||
} catch (e) {
|
||||
}
|
||||
;
|
||||
selection.removeRange(range);
|
||||
});
|
||||
if (container.classList.contains("highlight")) {
|
||||
container.appendChild(copybutton);
|
||||
} else if (container.parentNode.firstChild == container) {
|
||||
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
|
||||
codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
|
||||
} else {
|
||||
codeblock.parentNode.appendChild(copybutton);
|
||||
}
|
||||
}
|
||||
window.addEventListener("DOMContentLoaded", (event) => {
|
||||
document.querySelectorAll("pre > code").forEach((codeblock) => createCopyButton(codeblock));
|
||||
});
|
||||
})();
|
||||
134
public/js/search.js
Normal file
134
public/js/search.js
Normal file
@@ -0,0 +1,134 @@
|
||||
(() => {
|
||||
// <stdin>
|
||||
var seachOpnBtn = null;
|
||||
var closeBtn = null;
|
||||
var searchCntr = null;
|
||||
var resultCntr = null;
|
||||
var searchBtn = null;
|
||||
var searchTxt = null;
|
||||
var isSearchOpen = false;
|
||||
var isJsonIndexed = false;
|
||||
var isResEmpty = true;
|
||||
var fuse;
|
||||
function fetchJSON(path, callback) {
|
||||
var httpRequest = new XMLHttpRequest();
|
||||
httpRequest.onreadystatechange = function() {
|
||||
if (httpRequest.readyState === 4) {
|
||||
if (httpRequest.status === 200) {
|
||||
var data = JSON.parse(httpRequest.responseText);
|
||||
if (callback) callback(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
httpRequest.open("GET", path);
|
||||
httpRequest.send();
|
||||
}
|
||||
function buildIndex() {
|
||||
var baseURL = searchCntr.getAttribute("data-url");
|
||||
baseURL = baseURL.replace(/\/?$/, "/");
|
||||
fetchJSON(baseURL + "index.json", function(data) {
|
||||
var options = {
|
||||
shouldSort: true,
|
||||
ignoreLocation: true,
|
||||
threshold: 0,
|
||||
includeMatches: true,
|
||||
keys: [
|
||||
{ name: "title", weight: 0.8 },
|
||||
{ name: "section", weight: 0.2 },
|
||||
{ name: "summary", weight: 0.6 },
|
||||
{ name: "content", weight: 0.4 }
|
||||
]
|
||||
};
|
||||
fuse = new Fuse(data, options);
|
||||
isJsonIndexed = true;
|
||||
});
|
||||
}
|
||||
function openSearch() {
|
||||
if (!isJsonIndexed) {
|
||||
buildIndex();
|
||||
}
|
||||
if (!isSearchOpen) {
|
||||
searchCntr.style.display = "flex";
|
||||
document.body.style.overflow = "hidden";
|
||||
isSearchOpen = true;
|
||||
searchTxt.focus();
|
||||
}
|
||||
}
|
||||
function closeSearch() {
|
||||
if (isSearchOpen) {
|
||||
searchCntr.style.display = "none";
|
||||
document.body.style.overflow = "";
|
||||
isSearchOpen = false;
|
||||
}
|
||||
}
|
||||
function executeQuery(query) {
|
||||
let results = fuse.search(query);
|
||||
let resultsHtml = "";
|
||||
if (results.length > 1) {
|
||||
results.forEach(function(value, key) {
|
||||
var meta = value.item.section + " | ";
|
||||
meta = meta + value.item.date ? value.item.date + " | " : "";
|
||||
meta = meta + `<span class="srch-link">${value.item.permalink}</span>`;
|
||||
resultsHtml = resultsHtml + `<li><a href="${value.item.permalink}">
|
||||
<p class="srch-title">${value.item.title}</p>
|
||||
<p class="srch-meta">${meta}</p>
|
||||
<p class="srch-smry">${value.item.summary}</p>
|
||||
</a></li>`;
|
||||
});
|
||||
isResEmpty = false;
|
||||
} else {
|
||||
resultsHtml = "";
|
||||
isResEmpty = true;
|
||||
}
|
||||
resultCntr.innerHTML = resultsHtml;
|
||||
}
|
||||
window.addEventListener("DOMContentLoaded", (event) => {
|
||||
seachOpnBtn = document.getElementById("search-open");
|
||||
searchBtn = document.getElementById("search-btn");
|
||||
closeBtn = document.getElementById("search-close");
|
||||
searchCntr = document.getElementById("search-container");
|
||||
resultCntr = document.getElementById("search-results");
|
||||
searchTxt = document.getElementById("search-query");
|
||||
seachOpnBtn.addEventListener("click", openSearch);
|
||||
closeBtn.addEventListener("click", closeSearch);
|
||||
searchTxt.onkeyup = function(event2) {
|
||||
executeQuery(this.value);
|
||||
};
|
||||
searchTxt.onkeydown = function(event2) {
|
||||
if (event2.key == "Enter" && !isResEmpty) {
|
||||
resultCntr.firstChild.firstElementChild.focus();
|
||||
event2.preventDefault();
|
||||
}
|
||||
};
|
||||
});
|
||||
document.addEventListener("keydown", function(event) {
|
||||
if (event.key == "/") {
|
||||
event.preventDefault();
|
||||
openSearch();
|
||||
}
|
||||
if (isSearchOpen) {
|
||||
if (event.key == "Escape") {
|
||||
event.preventDefault();
|
||||
closeSearch();
|
||||
} else if (event.key == "ArrowDown" && !isResEmpty) {
|
||||
if (document.activeElement == searchTxt) {
|
||||
resultCntr.firstChild.firstElementChild.focus();
|
||||
} else if (document.activeElement == resultCntr.lastChild.firstElementChild) {
|
||||
searchTxt.focus();
|
||||
} else {
|
||||
document.activeElement.parentElement.nextSibling.firstElementChild.focus();
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (event.key == "ArrowUp" && !isResEmpty) {
|
||||
if (document.activeElement == searchTxt) {
|
||||
resultCntr.lastChild.firstElementChild.focus();
|
||||
} else if (document.activeElement == resultCntr.firstChild.firstElementChild) {
|
||||
searchTxt.focus();
|
||||
} else {
|
||||
document.activeElement.parentElement.previousSibling.firstElementChild.focus();
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
25
public/js/theme.js
Normal file
25
public/js/theme.js
Normal file
@@ -0,0 +1,25 @@
|
||||
(() => {
|
||||
// <stdin>
|
||||
function toggleTheme() {
|
||||
if (document.body.className.includes("dark")) {
|
||||
document.body.classList.remove("dark");
|
||||
localStorage.setItem("theme", "light");
|
||||
} else {
|
||||
document.body.classList.add("dark");
|
||||
localStorage.setItem("theme", "dark");
|
||||
}
|
||||
}
|
||||
window.addEventListener("DOMContentLoaded", (event) => {
|
||||
const switcher = document.getElementById("theme-switcher");
|
||||
if (switcher) {
|
||||
switcher.addEventListener("click", () => {
|
||||
toggleTheme();
|
||||
});
|
||||
}
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (event2) => {
|
||||
if (event2.matches && localStorage.getItem("theme") === "light") {
|
||||
toggleTheme();
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user