(function () {
self.addEventListener("DOMContentLoaded", function () {
/*
Originally Based on fixedsearch, a super fast, client side search for Hugo.io with Fusejs.io
based on https://gist.github.com/cmod/5410eae147e4318164258742dd053993
*/
const form = document.getElementById("search-form"); // search form
const query = document.getElementById("search-input"); // input box for search
const submit = document.getElementById("search-submit"); // form submit button
const dropdown = document.getElementById("search-results"); // targets the
const container = document.getElementById("search-frame"); // targets the upper parent container
form.addEventListener("focusin", function () {
initialize();
});
form.addEventListener("submit", function (event) {
event.preventDefault();
return false;
});
form.addEventListener("keydown", function (event) {
const head =
dropdown.firstChild.nextElementSibling.firstChild.nextElementSibling;
const tail = dropdown.lastElementChild.firstChild.nextElementSibling;
// ESC (27)
if (query.contains(event.target)) {
if (event.keyCode == 27) {
document.activeElement.blur();
dropdown.setAttribute("hidden", "");
}
}
// DOWN (40)
if (event.keyCode == 40) {
event.preventDefault();
if (document.activeElement == query) head.focus();
else if (document.activeElement == tail) query.focus();
else {
document.activeElement.parentElement.nextElementSibling.firstChild
.nextElementSibling.focus();
}
}
// UP (38)
if (event.keyCode == 38) {
event.preventDefault();
if (document.activeElement == query) tail.focus();
else if (document.activeElement == head) query.focus();
else {
document.activeElement.parentElement.previousElementSibling.firstChild
.nextElementSibling.focus();
}
}
// BACKSPACE (8)
if (event.keyCode == 8) {
if (document.activeElement != query) {
event.preventDefault();
query.focus();
}
}
// ENTER (13)
if (event.keyCode == 13) {
if (dropdown && document.activeElement == query) {
event.preventDefault();
head.focus();
self.window.location = document.activeElement.href;
}
}
});
let scrolls = 0;
self.addEventListener("scroll", function () {
if (scrolls > 3) {
scrolls = 0;
document.activeElement.blur();
dropdown.setAttribute("hidden", "");
container.removeAttribute("data-focus");
}
scrolls++;
});
document.addEventListener("click", function (event) {
if (!form.contains(event.target)) {
dropdown.setAttribute("hidden", "");
container.removeAttribute("data-focus");
}
});
let data = {};
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
function appendItemsTo(local, remote) {
const paginated = Object.keys(remote).includes("next_url");
if (isEmpty(local)) {
local = remote;
} else {
local.items = local.items.concat(remote.items);
}
if (paginated) {
fetchJson(remote.next_url, local);
}
data = local;
}
function fetchJson(url, store) {
const httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === 4 && httpRequest.status === 200) {
appendItemsTo(store, JSON.parse(httpRequest.responseText));
}
};
httpRequest.open("GET", url);
httpRequest.send();
}
/* Load script based on https://stackoverflow.com/a/55451823 */
function loadScript(url) {
return new Promise(function (resolve, reject) {
const script = document.createElement("script");
script.onerror = reject;
script.onload = resolve;
if (document.currentScript) {
document.currentScript.parentNode.insertBefore(
script,
document.currentScript,
);
} else {
document.head.appendChild(script);
}
script.src = url;
});
}
let firstRun = true;
function initialize() {
if (firstRun) {
loadScript(window.location.origin + "/js/fuzzysort.js")
.then(() => {
firstRun = false;
fetchJson("/index.json", {});
const options = { key: ["title"] };
query.addEventListener("keyup", function () {
search(query.value, data.items, options);
});
query.addEventListener("focusin", function () {
search(query.value, data.items, options);
});
search(query.value, data.items, options);
}).catch((error) => {
console.log("Error failed to load fuzzy sort: " + error);
});
}
}
function search(term, data, options) {
const results = fuzzysort.go(term, data, options);
let items = "";
if (results.length === 0 && term.length >= 0) {
let separator = "—";
if (term.length === 0) separator = "";
items = `
-
${term} ${separator} No Results Found
`;
dropdown.removeAttribute("hidden");
container.setAttribute("data-focus", "");
} else {
dropdown.removeAttribute("hidden");
for (const string in results.slice(0, 10)) {
const title = results[string].obj.title;
let highlight = fuzzysort.highlight(
fuzzysort.single(term, title),
"",
"",
);
if (highlight === null) {
highlight = title;
}
items = items +
`
-
${highlight}
`;
}
}
dropdown.innerHTML = items;
}
});
})();