From 09ff2dba94fa3fcdcb9abca5def638a9522affae Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Tue, 1 Oct 2024 17:13:29 +0200 Subject: [PATCH] Fork search script from hugo-book --- assets/search.js | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 assets/search.js diff --git a/assets/search.js b/assets/search.js new file mode 100644 index 00000000..91add6fc --- /dev/null +++ b/assets/search.js @@ -0,0 +1,113 @@ +'use strict'; + +{{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }} +{{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }} +{{ $searchConfig := i18n "bookSearchConfig" | default "{}" }} + +(function () { + const searchDataURL = '{{ $searchData.RelPermalink }}'; + const indexConfig = Object.assign({{ $searchConfig }}, { + includeScore: true, + useExtendedSearch: true, + fieldNormWeight: 1.5, + threshold: 0.2, + ignoreLocation: true, + keys: [ + { + name: 'title', + weight: 0.7 + }, + { + name: 'content', + weight: 0.3 + } + ] + }); + + const input = document.querySelector('#book-search-input'); + const results = document.querySelector('#book-search-results'); + + if (!input) { + return + } + + input.addEventListener('focus', init); + input.addEventListener('keyup', search); + + document.addEventListener('keypress', focusSearchFieldOnKeyPress); + + /** + * @param {Event} event + */ + function focusSearchFieldOnKeyPress(event) { + if (event.target.value !== undefined) { + return; + } + + if (input === document.activeElement) { + return; + } + + const characterPressed = String.fromCharCode(event.charCode); + if (!isHotkey(characterPressed)) { + return; + } + + input.focus(); + event.preventDefault(); + } + + /** + * @param {String} character + * @returns {Boolean} + */ + function isHotkey(character) { + const dataHotkeys = input.getAttribute('data-hotkeys') || ''; + return dataHotkeys.indexOf(character) >= 0; + } + + function init() { + input.removeEventListener('focus', init); // init once + input.required = true; + + fetch(searchDataURL) + .then(pages => pages.json()) + .then(pages => { + window.bookSearchIndex = new Fuse(pages, indexConfig); + }) + .then(() => input.required = false) + .then(search); + } + + function search() { + while (results.firstChild) { + results.removeChild(results.firstChild); + } + + if (!input.value) { + return; + } + + const searchHits = window.bookSearchIndex.search(input.value).slice(0,10); + searchHits.forEach(function (page) { + const li = element('
  • '); + const a = li.querySelector('a'), small = li.querySelector('small'); + + a.href = page.item.href; + a.textContent = page.item.title; + small.textContent = page.item.section; + + results.appendChild(li); + }); + } + + /** + * @param {String} content + * @returns {Node} + */ + function element(content) { + const div = document.createElement('div'); + div.innerHTML = content; + return div.firstChild; + } +})();