Files
fundor333.com/layouts/partials/search-index.html

179 lines
4.9 KiB
HTML

<template id="search-result" hidden>
<article class="content post post-item">
<h4 class="post-title post-item-title"><a class="read-more-link"><i class="fa-duotone fa-regular fa-flag-pennant"></i> <a
class="summary-title-link"></a></a></h4>
<summary class="summary" hidden></summary>
<div class="read-more-container">
<time class="post-item-meta"></time>
</div>
</article>
</template>
<script>
window.addEventListener("DOMContentLoaded", function(event)
{
var index = null;
var lookup = null;
var queuedTerm = null;
var form = document.getElementById("search");
var input = document.getElementById("search-input");
const params = new URLSearchParams(window.location.search)
const query = params.get('q')
startSearch(query)
form.addEventListener("submit", function(event)
{
event.preventDefault();
var term = input.value.trim();
if (!term)
return;
startSearch(term);
}, false);
function startSearch(term)
{
// Start icon animation.
form.setAttribute("data-running", "true");
if (index)
{
// Index already present, search directly.
search(term);
}
else if (queuedTerm)
{
// Index is being loaded, replace the term we want to search for.
queuedTerm = term;
}
else
{
// Start loading index, perform the search when done.
queuedTerm = term;
initIndex();
}
}
function searchDone()
{
// Stop icon animation.
form.removeAttribute("data-running");
queuedTerm = null;
}
function initIndex()
{
var request = new XMLHttpRequest();
request.open("GET", "/search.json");
request.responseType = "json";
request.addEventListener("load", function(event)
{
lookup = {};
index = lunr(function()
{
// Uncomment the following line and replace de by the right language
// code to use a lunr language pack.
// this.use(lunr.de);
this.ref("uri");
// If you added more searchable fields to the search index, list them here.
this.field("title");
this.field("content");
this.field("description");
this.field("categories");
this.field("date");
for (var doc of request.response)
{
this.add(doc);
lookup[doc.uri] = doc;
}
});
// Search index is ready, perform the search now
search(queuedTerm);
}, false);
request.addEventListener("error", searchDone, false);
request.send(null);
}
function search(term)
{
var results = index.search(term);
// The element where search results should be displayed, adjust as needed.
var target = document.querySelector(".main-inner");
while (target.firstChild)
target.removeChild(target.firstChild);
var title = document.createElement("h1");
title.id = "search-results";
title.className = "list-title";
if (results.length == 0)
title.textContent = `No results found for “${term}`;
else if (results.length == 1)
title.textContent = `Found one result for “${term}`;
else
title.textContent = `Found ${results.length} results for “${term}`;
target.appendChild(title);
document.title = title.textContent;
var template = document.getElementById("search-result");
for (var result of results)
{
var doc = lookup[result.ref];
// Fill out search result template, adjust as needed.
var element = template.content.cloneNode(true);
element.querySelector(".summary-title-link").href =
element.querySelector(".read-more-link").href = doc.uri;
element.querySelector(".summary-title-link").textContent = doc.title;
element.querySelector(".summary").textContent = truncate(doc.content, 70);
element.querySelector(".post-item-meta").textContent = doc.date;
target.appendChild(element);
}
title.scrollIntoView(true);
searchDone();
}
// This matches Hugo's own summary logic:
// https://github.com/gohugoio/hugo/blob/b5f39d23b8/helpers/content.go#L543
function truncate(text, minWords)
{
var match;
var result = "";
var wordCount = 0;
var regexp = /(\S+)(\s*)/g;
while (match = regexp.exec(text))
{
wordCount++;
if (wordCount <= minWords)
result += match[0];
else
{
var char1 = match[1][match[1].length - 1];
var char2 = match[2][0];
if (/[.?!"]/.test(char1) || char2 == "\n")
{
result += match[1];
break;
}
else
result += match[0];
}
}
return result;
}
}, false);
</script>