2021-04-09 21:28:23 +02:00
|
|
|
import * as params from '@params';
|
|
|
|
|
2020-12-06 13:49:50 +01:00
|
|
|
var fuse; // holds our search engine
|
2020-12-18 07:15:10 +01:00
|
|
|
var resList = document.getElementById('searchResults');
|
|
|
|
var sInput = document.getElementById('searchInput');
|
2021-04-09 21:29:24 +02:00
|
|
|
var first, last, current_elem = null
|
2020-12-18 07:15:10 +01:00
|
|
|
var resultsAvailable = false;
|
2020-12-06 13:49:50 +01:00
|
|
|
|
2021-04-09 21:28:23 +02:00
|
|
|
// load our search index
|
|
|
|
window.onload = function () {
|
2020-12-06 13:49:50 +01:00
|
|
|
var xhr = new XMLHttpRequest();
|
|
|
|
xhr.onreadystatechange = function () {
|
|
|
|
if (xhr.readyState === 4) {
|
|
|
|
if (xhr.status === 200) {
|
|
|
|
var data = JSON.parse(xhr.responseText);
|
|
|
|
if (data) {
|
|
|
|
// fuse.js options; check fuse.js website for details
|
|
|
|
var options = {
|
|
|
|
distance: 100,
|
|
|
|
threshold: 0.4,
|
2021-01-30 07:26:09 +01:00
|
|
|
ignoreLocation: true,
|
2020-12-06 13:49:50 +01:00
|
|
|
keys: [
|
|
|
|
'title',
|
|
|
|
'permalink',
|
|
|
|
'summary',
|
|
|
|
'content'
|
|
|
|
]
|
|
|
|
};
|
2021-04-09 21:28:23 +02:00
|
|
|
if (params.fuseOpts) options = params.fuseOpts;
|
2020-12-06 13:49:50 +01:00
|
|
|
fuse = new Fuse(data, options); // build the index from the json file
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
console.log(xhr.responseText);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
xhr.open('GET', "../index.json");
|
|
|
|
xhr.send();
|
|
|
|
}
|
|
|
|
|
2021-04-09 21:29:24 +02:00
|
|
|
function activeToggle(ae) {
|
|
|
|
document.querySelectorAll('.focus').forEach(function (element) {
|
|
|
|
// rm focus class
|
|
|
|
element.classList.remove("focus")
|
|
|
|
});
|
|
|
|
if (ae) {
|
|
|
|
ae.focus()
|
|
|
|
document.activeElement = current_elem = ae;
|
|
|
|
ae.parentElement.classList.add("focus")
|
|
|
|
} else {
|
|
|
|
document.activeElement.parentElement.classList.add("focus")
|
|
|
|
}
|
2021-02-07 17:04:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function reset() {
|
|
|
|
resultsAvailable = false;
|
|
|
|
resList.innerHTML = sInput.value = ''; // clear inputbox and searchResults
|
|
|
|
sInput.focus(); // shift focus to input box
|
2020-12-18 07:15:10 +01:00
|
|
|
}
|
|
|
|
|
2020-12-06 13:49:50 +01:00
|
|
|
// execute search as each character is typed
|
2021-01-16 08:56:55 +01:00
|
|
|
sInput.onkeyup = function (e) {
|
2020-12-06 13:49:50 +01:00
|
|
|
// run a search query (for "term") every time a letter is typed
|
|
|
|
// in the search box
|
2021-04-09 21:28:40 +02:00
|
|
|
if (fuse) {
|
|
|
|
const results = fuse.search(this.value.trim()); // the actual query being run using fuse.js
|
|
|
|
if (results.length !== 0) {
|
|
|
|
// build our html if result exists
|
|
|
|
let resultSet = ''; // our results bucket
|
2020-12-06 13:49:50 +01:00
|
|
|
|
2021-04-09 21:28:40 +02:00
|
|
|
for (let item in results) {
|
|
|
|
resultSet += `<li class="post-entry"><header class="entry-header">${results[item].item.title} »</header>` +
|
|
|
|
`<a href="${results[item].item.permalink}" aria-label="${results[item].item.title}"></a></li>`
|
|
|
|
}
|
2020-12-06 13:49:50 +01:00
|
|
|
|
2021-04-09 21:28:40 +02:00
|
|
|
resList.innerHTML = resultSet;
|
|
|
|
resultsAvailable = true;
|
|
|
|
first = resList.firstChild;
|
|
|
|
last = resList.lastChild;
|
|
|
|
} else {
|
|
|
|
resultsAvailable = false;
|
|
|
|
resList.innerHTML = '';
|
2020-12-06 13:49:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-07 17:04:34 +01:00
|
|
|
sInput.addEventListener('search', function (e) {
|
|
|
|
// clicked on x
|
|
|
|
if (!this.value) reset()
|
|
|
|
})
|
|
|
|
|
2020-12-18 07:15:10 +01:00
|
|
|
// kb bindings
|
|
|
|
document.onkeydown = function (e) {
|
|
|
|
let key = e.key;
|
2021-04-09 21:29:24 +02:00
|
|
|
var ae = document.activeElement;
|
|
|
|
|
2020-12-18 16:55:34 +01:00
|
|
|
let inbox = document.getElementById("searchbox").contains(ae)
|
2020-12-18 07:15:10 +01:00
|
|
|
|
2021-01-16 08:56:55 +01:00
|
|
|
if (ae === sInput) {
|
2021-02-07 17:04:34 +01:00
|
|
|
var elements = document.getElementsByClassName('focus');
|
2021-01-16 08:56:55 +01:00
|
|
|
while (elements.length > 0) {
|
2021-02-07 17:04:34 +01:00
|
|
|
elements[0].classList.remove('focus');
|
2021-01-16 08:56:55 +01:00
|
|
|
}
|
2021-04-09 21:29:24 +02:00
|
|
|
} else if (current_elem) ae = current_elem;
|
2021-01-16 08:56:55 +01:00
|
|
|
|
2020-12-18 16:55:34 +01:00
|
|
|
if (key === "ArrowDown" && resultsAvailable && inbox) {
|
2020-12-18 07:15:10 +01:00
|
|
|
e.preventDefault();
|
|
|
|
if (ae == sInput) {
|
|
|
|
// if the currently focused element is the search input, focus the <a> of first <li>
|
2021-04-09 21:29:24 +02:00
|
|
|
activeToggle(resList.firstChild.lastChild);
|
2020-12-18 07:15:10 +01:00
|
|
|
} else if (ae.parentElement == last) {
|
|
|
|
// if the currently focused element's parent is last, do nothing
|
|
|
|
} else {
|
|
|
|
// otherwise select the next search result
|
2021-04-09 21:29:24 +02:00
|
|
|
activeToggle(ae.parentElement.nextSibling.lastChild);
|
2020-12-18 07:15:10 +01:00
|
|
|
}
|
2020-12-18 16:55:34 +01:00
|
|
|
} else if (key === "ArrowUp" && resultsAvailable && inbox) {
|
2020-12-18 07:15:10 +01:00
|
|
|
e.preventDefault();
|
|
|
|
if (ae == sInput) {
|
|
|
|
// if the currently focused element is input box, do nothing
|
|
|
|
} else if (ae.parentElement == first) {
|
|
|
|
// if the currently focused element is first item, go to input box
|
2021-04-09 21:29:24 +02:00
|
|
|
activeToggle(sInput);
|
2020-12-18 07:15:10 +01:00
|
|
|
} else {
|
|
|
|
// otherwise select the previous search result
|
2021-04-09 21:29:24 +02:00
|
|
|
activeToggle(ae.parentElement.previousSibling.lastChild);
|
2020-12-18 07:15:10 +01:00
|
|
|
}
|
2020-12-18 16:55:34 +01:00
|
|
|
} else if (key === "ArrowRight" && resultsAvailable && inbox) {
|
2020-12-18 07:15:10 +01:00
|
|
|
ae.click(); // click on active link
|
|
|
|
} else if (key === "Escape") {
|
2021-02-07 17:04:34 +01:00
|
|
|
reset()
|
2020-12-18 07:15:10 +01:00
|
|
|
}
|
|
|
|
}
|