123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- 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;
- // 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);
- }
- }
- };
- 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")
- }
- }
- function reset() {
- resultsAvailable = false;
- resList.innerHTML = sInput.value = ''; // clear inputbox and searchResults
- sInput.focus(); // shift focus to input box
- }
- // 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
- }
- if (results.length !== 0) {
- // build our html if result exists
- let resultSet = ''; // our results bucket
- 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>`
- }
- resList.innerHTML = resultSet;
- resultsAvailable = true;
- first = resList.firstChild;
- last = resList.lastChild;
- } else {
- resultsAvailable = false;
- resList.innerHTML = '';
- }
- }
- }
- sInput.addEventListener('search', function (e) {
- // clicked on x
- if (!this.value) reset()
- })
- // kb bindings
- document.onkeydown = function (e) {
- let key = e.key;
- let ae = document.activeElement;
- let inbox = document.getElementById("searchbox").contains(ae)
- if (ae === sInput) {
- let elements = document.getElementsByClassName('focus');
- while (elements.length > 0) {
- elements[0].classList.remove('focus');
- }
- } else if (current_elem) ae = current_elem;
- if (key === "Escape") {
- reset()
- } else if (!resultsAvailable || !inbox) {
- return
- } else if (key === "ArrowDown") {
- e.preventDefault();
- if (ae == sInput) {
- // if the currently focused element is the search input, focus the <a> of first <li>
- activeToggle(resList.firstChild.lastChild);
- } else if (ae.parentElement != last) {
- // if the currently focused element's parent is last, do nothing
- // otherwise select the next search result
- activeToggle(ae.parentElement.nextSibling.lastChild);
- }
- } else if (key === "ArrowUp") {
- e.preventDefault();
- if (ae.parentElement == first) {
- // if the currently focused element is first item, go to input box
- activeToggle(sInput);
- } else if (ae != sInput) {
- // if the currently focused element is input box, do nothing
- // otherwise select the previous search result
- activeToggle(ae.parentElement.previousSibling.lastChild);
- }
- } else if (key === "ArrowRight") {
- ae.click(); // click on active link
- }
- }
|