summaryrefslogtreecommitdiff
path: root/themes/hugo-book/assets/search.js
diff options
context:
space:
mode:
authoraethrvmn <me@aethrvmn.gr>2025-08-30 13:17:32 +0000
committeraethrvmn <me@aethrvmn.gr>2025-08-30 13:17:32 +0000
commit1147a663e70aadb2578cbe601bc723d7cd939c5a (patch)
treeb5100d2031328be3cfd3e9ae62730436bd573e0f /themes/hugo-book/assets/search.js
parentadded .gitignore (diff)
added non-content
Diffstat (limited to '')
-rw-r--r--themes/hugo-book/assets/search.js113
1 files changed, 113 insertions, 0 deletions
diff --git a/themes/hugo-book/assets/search.js b/themes/hugo-book/assets/search.js
new file mode 100644
index 0000000..91add6f
--- /dev/null
+++ b/themes/hugo-book/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('<li><a href></a><small></small></li>');
+ 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;
+ }
+})();
Directive (EU) 2019/790, Article 4(3); all rights regarding Text and Data Mining (TDM) are reserved.