diff --git a/assets/js/fastsearch.js b/assets/js/fastsearch.js
index 53364d10..cb4eabfd 100644
--- a/assets/js/fastsearch.js
+++ b/assets/js/fastsearch.js
@@ -1,156 +1,194 @@
import * as params from '@params';
-let fuse; // holds our search engine
-let resList = document.getElementById('searchResults');
-let sInput = document.getElementById('searchInput');
-let first, last, current_elem = null
-let resultsAvailable = false;
+const resList = document.getElementById('searchResults');
+const sInput = document.getElementById('searchInput');
+const searchBox = document.getElementById('searchbox');
-// load our search index
-window.onload = function () {
- let xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- let data = JSON.parse(xhr.responseText);
- if (data) {
- // fuse.js options; check fuse.js website for details
- let options = {
- distance: 100,
- threshold: 0.4,
- ignoreLocation: true,
- keys: [
- 'title',
- 'permalink',
- 'summary',
- 'content'
- ]
- };
- if (params.fuseOpts) {
- options = {
- isCaseSensitive: params.fuseOpts.iscasesensitive ?? false,
- includeScore: params.fuseOpts.includescore ?? false,
- includeMatches: params.fuseOpts.includematches ?? false,
- minMatchCharLength: params.fuseOpts.minmatchcharlength ?? 1,
- shouldSort: params.fuseOpts.shouldsort ?? true,
- findAllMatches: params.fuseOpts.findallmatches ?? false,
- keys: params.fuseOpts.keys ?? ['title', 'permalink', 'summary', 'content'],
- location: params.fuseOpts.location ?? 0,
- threshold: params.fuseOpts.threshold ?? 0.4,
- distance: params.fuseOpts.distance ?? 100,
- ignoreLocation: params.fuseOpts.ignorelocation ?? true
- }
- }
- fuse = new Fuse(data, options); // build the index from the json file
- }
- } else {
- console.log(xhr.responseText);
- }
- }
+let fuse;
+let currentElement = null;
+let firstResult = null;
+let lastResult = null;
+
+const defaultFuseOptions = {
+ distance: 100,
+ threshold: 0.4,
+ ignoreLocation: true,
+ keys: ['title', 'permalink', 'summary', 'content']
+};
+
+const buildFuseOptions = () => {
+ if (!params.fuseOpts) {
+ return defaultFuseOptions;
+ }
+
+ return {
+ isCaseSensitive: params.fuseOpts.iscasesensitive ?? false,
+ includeScore: params.fuseOpts.includescore ?? false,
+ includeMatches: params.fuseOpts.includematches ?? false,
+ minMatchCharLength: params.fuseOpts.minmatchcharlength ?? 1,
+ shouldSort: params.fuseOpts.shouldsort ?? true,
+ findAllMatches: params.fuseOpts.findallmatches ?? false,
+ keys: params.fuseOpts.keys ?? defaultFuseOptions.keys,
+ location: params.fuseOpts.location ?? 0,
+ threshold: params.fuseOpts.threshold ?? defaultFuseOptions.threshold,
+ distance: params.fuseOpts.distance ?? defaultFuseOptions.distance,
+ ignoreLocation: params.fuseOpts.ignorelocation ?? defaultFuseOptions.ignoreLocation
};
- xhr.open('GET', "../index.json");
- xhr.send();
-}
+};
-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")
+const debounce = (fn, delay) => {
+ let timeout;
+ return (...args) => {
+ clearTimeout(timeout);
+ timeout = window.setTimeout(() => fn(...args), delay);
+ };
+};
+
+const reset = () => {
+ currentElement = null;
+ firstResult = null;
+ lastResult = null;
+ resList.innerHTML = '';
+ sInput.value = '';
+ sInput.focus();
+};
+
+const setActiveResult = (element) => {
+ document.querySelectorAll('.focus').forEach((item) => item.classList.remove('focus'));
+
+ if (!element) {
+ return;
}
-}
-function reset() {
- resultsAvailable = false;
- resList.innerHTML = sInput.value = ''; // clear inputbox and searchResults
- sInput.focus(); // shift focus to input box
-}
+ element.focus();
+ element.parentElement?.classList.add('focus');
+ currentElement = element;
+};
-// execute search as each character is typed
-sInput.onkeyup = function (e) {
- // run a search query (for "term") every time a letter is typed
- // in the search box
- if (fuse) {
- let results;
- if (params.fuseOpts) {
- results = fuse.search(this.value.trim(), { limit: params.fuseOpts.limit }); // the actual query being run using fuse.js along with options
- } else {
- results = fuse.search(this.value.trim()); // the actual query being run using fuse.js
+const renderResults = (results) => {
+ if (!Array.isArray(results) || results.length === 0) {
+ resList.innerHTML = '';
+ firstResult = lastResult = currentElement = null;
+ return;
+ }
+
+ const fragment = document.createDocumentFragment();
+
+ for (const result of results) {
+ const li = document.createElement('li');
+ const titleText = document.createTextNode(result.item.title);
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ svg.setAttribute('width', '24');
+ svg.setAttribute('height', '24');
+ svg.setAttribute('viewBox', '0 0 24 24');
+ svg.setAttribute('fill', 'none');
+ svg.setAttribute('stroke', 'currentColor');
+ svg.setAttribute('stroke-width', '2');
+ svg.setAttribute('stroke-linecap', 'round');
+ svg.setAttribute('stroke-linejoin', 'round');
+ svg.classList.add('feather', 'feather-chevrons-right');
+
+ svg.innerHTML = '