Skip to content

Commit f7952a8

Browse files
committed
libs
1 parent 5f4c5a3 commit f7952a8

5 files changed

Lines changed: 126 additions & 0 deletions

File tree

docs/assets/js/search.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
(function () {
2+
function normaliseQuery(value) {
3+
return (value || '').trim();
4+
}
5+
6+
function buildSnippet(text, summary, match) {
7+
if (!match || !match.indices || !match.indices.length) {
8+
return summary || '';
9+
}
10+
11+
let first = match.indices[0];
12+
let start = Math.max(0, first[0] - 90);
13+
let end = Math.min(text.length, first[1] + 91);
14+
let snippet = text.slice(start, end).trim();
15+
if (start > 0) {
16+
snippet = '...' + snippet;
17+
}
18+
if (end < text.length) {
19+
snippet += '...';
20+
}
21+
return snippet;
22+
}
23+
24+
function renderResults(resultsElement, statusElement, query, matches) {
25+
resultsElement.innerHTML = '';
26+
27+
if (!query) {
28+
statusElement.textContent = 'Enter a search term.';
29+
return;
30+
}
31+
32+
statusElement.textContent = matches.length ? `${matches.length} result(s)` : 'No results match your query.';
33+
34+
matches.forEach((result) => {
35+
let item = result.item;
36+
let li = document.createElement('li');
37+
li.className = 'search-result';
38+
39+
let title = document.createElement('a');
40+
title.className = 'search-result-title';
41+
title.href = item.path;
42+
title.textContent = item.title;
43+
li.appendChild(title);
44+
45+
let meta = document.createElement('div');
46+
meta.className = 'search-result-meta';
47+
meta.textContent = item.kind;
48+
li.appendChild(meta);
49+
50+
let textMatch = (result.matches || []).find((match) => match.key === 'text' || match.key === 'headings');
51+
let summary = document.createElement('p');
52+
summary.className = 'search-result-summary';
53+
summary.textContent = buildSnippet(item.text, item.summary, textMatch);
54+
li.appendChild(summary);
55+
56+
resultsElement.appendChild(li);
57+
});
58+
}
59+
60+
async function initialiseSearch() {
61+
let app = document.getElementById('search-app');
62+
if (!app) {
63+
return;
64+
}
65+
66+
let statusElement = document.getElementById('search-status');
67+
let resultsElement = document.getElementById('search-results');
68+
let input = document.getElementById('page-search-input');
69+
let params = new URLSearchParams(window.location.search);
70+
let query = normaliseQuery(params.get('query'));
71+
document.querySelectorAll('input[name="query"]').forEach((element) => {
72+
element.value = query;
73+
});
74+
75+
try {
76+
let response = await fetch(window.appconfig.searchIndex);
77+
if (!response.ok) {
78+
throw new Error(`Failed to load search index: ${response.status}`);
79+
}
80+
81+
let documents = await response.json();
82+
let fuse = new Fuse(documents, {
83+
includeMatches: true,
84+
ignoreLocation: true,
85+
minMatchCharLength: 2,
86+
threshold: 0.3,
87+
keys: [
88+
{ name: 'title', weight: 3 },
89+
{ name: 'headings', weight: 2 },
90+
{ name: 'text', weight: 1 },
91+
],
92+
});
93+
94+
let matches = query ? fuse.search(query, { limit: 100 }) : [];
95+
renderResults(resultsElement, statusElement, query, matches);
96+
} catch (error) {
97+
console.error(error);
98+
statusElement.textContent = 'Failed to load the search index.';
99+
}
100+
}
101+
102+
document.addEventListener('DOMContentLoaded', initialiseSearch);
103+
}());

docs/assets/lib/feather-icons/feather.min.js

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)