summaryrefslogtreecommitdiff
path: root/docs/assets/js/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'docs/assets/js/index.js')
-rw-r--r--docs/assets/js/index.js169
1 files changed, 169 insertions, 0 deletions
diff --git a/docs/assets/js/index.js b/docs/assets/js/index.js
new file mode 100644
index 000000000..672d6c7a6
--- /dev/null
+++ b/docs/assets/js/index.js
@@ -0,0 +1,169 @@
+var suggestions = document.getElementById('suggestions');
+var search = document.getElementById('search');
+
+if (search !== null) {
+ document.addEventListener('keydown', inputFocus);
+}
+
+function inputFocus(e) {
+ if (e.ctrlKey && e.key === '/' ) {
+ e.preventDefault();
+ search.focus();
+ }
+ if (e.key === 'Escape' ) {
+ search.blur();
+ suggestions.classList.add('d-none');
+ }
+}
+
+document.addEventListener('click', function(event) {
+
+ var isClickInsideElement = suggestions.contains(event.target);
+
+ if (!isClickInsideElement) {
+ suggestions.classList.add('d-none');
+ }
+
+});
+
+/*
+Source:
+ - https://dev.to/shubhamprakash/trap-focus-using-javascript-6a3
+*/
+
+document.addEventListener('keydown',suggestionFocus);
+
+function suggestionFocus(e) {
+ const suggestionsHidden = suggestions.classList.contains('d-none');
+ if (suggestionsHidden) return;
+
+ const focusableSuggestions= [...suggestions.querySelectorAll('a')];
+ if (focusableSuggestions.length === 0) return;
+
+ const index = focusableSuggestions.indexOf(document.activeElement);
+
+ if (e.key === "ArrowUp") {
+ e.preventDefault();
+ const nextIndex = index > 0 ? index - 1 : 0;
+ focusableSuggestions[nextIndex].focus();
+ }
+ else if (e.key === "ArrowDown") {
+ e.preventDefault();
+ const nextIndex= index + 1 < focusableSuggestions.length ? index + 1 : index;
+ focusableSuggestions[nextIndex].focus();
+ }
+
+}
+
+/*
+Source:
+ - https://github.com/nextapps-de/flexsearch#index-documents-field-search
+ - https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html
+*/
+
+(function(){
+
+ var index = new FlexSearch.Document({
+ tokenize: "forward",
+ cache: 100,
+ document: {
+ id: 'id',
+ store: [
+ "href", "title", "description"
+ ],
+ index: ["title", "description", "content"]
+ }
+ });
+
+
+ // Not yet supported: https://github.com/nextapps-de/flexsearch#complex-documents
+
+ /*
+ var docs = [
+ {{ range $index, $page := (where .Site.Pages "Section" "docs") -}}
+ {
+ id: {{ $index }},
+ href: "{{ .Permalink }}",
+ title: {{ .Title | jsonify }},
+ description: {{ .Params.description | jsonify }},
+ content: {{ .Content | jsonify }}
+ },
+ {{ end -}}
+ ];
+ */
+
+ // https://discourse.gohugo.io/t/range-length-or-last-element/3803/2
+
+ {{ $list := (where .Site.RegularPages "Type" "in" (union .Site.Params.Sections.Search .Site.Params.Sections.Searchable)) -}}
+ {{ $len := (len $list) -}}
+
+ index.add(
+ {{ range $index, $element := $list -}}
+ {
+ id: {{ $index }},
+ href: "{{ .RelPermalink }}",
+ title: {{ .Title | jsonify }},
+ {{ with .Description -}}
+ description: {{ . | jsonify }},
+ {{ else -}}
+ description: {{ .Summary | plainify | jsonify }},
+ {{ end -}}
+ content: {{ .Plain | jsonify }}
+ })
+ {{ if ne (add $index 1) $len -}}
+ .add(
+ {{ end -}}
+ {{ end -}}
+ ;
+
+ search.addEventListener('input', show_results, true);
+
+ function show_results(){
+ const maxResult = 5;
+ var searchQuery = this.value;
+ var results = index.search(searchQuery, {limit: maxResult, enrich: true});
+
+ // flatten results since index.search() returns results for each indexed field
+ const flatResults = new Map(); // keyed by href to dedupe results
+ for (const result of results.flatMap(r => r.result)) {
+ if (flatResults.has(result.doc.href)) continue;
+ flatResults.set(result.doc.href, result.doc);
+ }
+
+ suggestions.innerHTML = "";
+ suggestions.classList.remove('d-none');
+
+ // inform user that no results were found
+ if (flatResults.size === 0 && searchQuery) {
+ const noResultsMessage = document.createElement('div')
+ noResultsMessage.innerHTML = `No results for "<strong>${searchQuery}</strong>"`
+ noResultsMessage.classList.add("suggestion__no-results");
+ suggestions.appendChild(noResultsMessage);
+ return;
+ }
+
+ // construct a list of suggestions
+ for(const [href, doc] of flatResults) {
+ const entry = document.createElement('div');
+ suggestions.appendChild(entry);
+
+ const a = document.createElement('a');
+ a.href = href;
+ entry.appendChild(a);
+
+ const title = document.createElement('span');
+ title.textContent = doc.title;
+ title.classList.add("suggestion__title");
+ a.appendChild(title);
+
+ const description = document.createElement('span');
+ description.textContent = doc.description;
+ description.classList.add("suggestion__description");
+ a.appendChild(description);
+
+ suggestions.appendChild(entry);
+
+ if(suggestions.childElementCount == maxResult) break;
+ }
+ }
+}());