1let query = new URLSearchParams(window.location.search).get("query"); 2let searchResultsContainer = document.getElementById('results'); 3let currentPage = 1; 4const resultsPerPage = 10; 5let pagefind; 6let loadMoreButton; // Cache reference to the load more button 7 8initPageFind(); 9 10async function initPageFind() { 11 pagefind = await import("https://www.truenas.com/docs/pagefind/pagefind.js"); 12 pagefind.init(); 13 14 if (query != null) { 15 document.getElementById("search-input").value = query; 16 await displaySearchResults(query, currentPage); 17 } 18} 19 20async function displaySearchResults(query, page) { 21 try { 22 let results = await pagefind.search(query); 23 let paginatedResults = results.results; 24 let slicedResults = await Promise.all(paginatedResults.map(r => r.data())); 25 26 let startIndex = (page - 1) * resultsPerPage; 27 let endIndex = startIndex + resultsPerPage; 28 let paginatedSlicedResults = slicedResults.slice(startIndex, endIndex); 29 30 if (loadMoreButton) { 31 loadMoreButton.classList.remove("loading"); 32 } 33 34 if (paginatedSlicedResults.length === 0) { 35 if (currentPage === 1) { 36 searchResultsContainer.innerHTML = 'No results found.'; 37 } else { 38 let noMoreResultsMessage = document.createElement('div'); 39 noMoreResultsMessage.innerHTML = '<p>No more results.</p>'; 40 searchResultsContainer.appendChild(noMoreResultsMessage); 41 } 42 } else { 43 let fragment = document.createDocumentFragment(); 44 45 paginatedSlicedResults.forEach((result, index) => { 46 let resultDiv = document.createElement('div'); 47 let title = result.meta.title.charAt(0).toUpperCase() + result.meta.title.slice(1); 48 49 // Add section marker in front of the <a> 50 let coreIcon = '<img src="https://www.truenas.com/docs/favicon/TN-favicon-32x32.png" alt="TrueNAS CORE" title="TrueNAS CORE" class="icon">'; 51 let scaleIcon = '<img src="https://www.truenas.com/docs/favicon/TN-favicon-32x32.png" alt="TrueNAS" title="TrueNAS" class="icon">'; 52 let tcIcon = '<img src="https://www.truenas.com/docs/favicon/TC-favicon-32x32.png" alt="TrueCommand" title="TrueCommand" class="icon">'; 53 54 let linkText = result.url.includes("/core/") ? `${coreIcon}` 55 : result.url.includes("/scale/") ? `${scaleIcon}` 56 : result.url.includes("/truecommand/") ? `${tcIcon}` 57 : result.url.includes("/solutions/") ? `Solutions:` 58 : result.url.includes("/hardware/") ? `TrueNAS Systems:` 59 : result.url.includes("/contributing/") ? `Contributing:` 60 : result.url.includes("/references/") ? `References:` 61 : result.url.includes("core_websocket") ? `${coreIcon}\u00A0API:` 62 : result.url.includes("scale_websocket") ? `${scaleIcon}\u00A0API:` 63 : `${title}:`; 64 65 resultDiv.innerHTML = ` 66 <h3>${linkText} <a href="${result.url}">${title}</a></h3> 67 <p>${result.excerpt}</p> 68 <hr> 69 `; 70 fragment.appendChild(resultDiv); 71 }); 72 73 // Append the new results fragment to existing content 74 searchResultsContainer.appendChild(fragment); 75 76 // Check if there are more results to display 77 const hasMoreResults = slicedResults.length > endIndex; 78 79 // Show/hide the load more button 80 if (hasMoreResults) { 81 if (!loadMoreButton) { 82 loadMoreButton = createLoadMoreButton(); 83 } 84 loadMoreButton.classList.remove("loading"); 85 loadMoreButton.style.display = 'block'; 86 } else if (loadMoreButton) { 87 loadMoreButton.style.display = 'none'; 88 } 89 } 90 91 } catch (error) { 92 console.error('Error:', error); 93 throw error; 94 } 95} 96 97async function loadMoreResults() { 98 currentPage++; 99 let query = new URLSearchParams(window.location.search).get("query"); 100 if (loadMoreButton) {
101 loadMoreButton.classList.add("loading"); 102 } 103 await displaySearchResults(query, currentPage); 104} 105 106function createLoadMoreButton() { 107 const button = document.createElement("a"); 108 button.classList.add("absolute-center"); 109 button.classList.add("button"); 110 button.textContent = "Load more results"; 111 button.id = "loadMoreButton"; 112 button.addEventListener('click', loadMoreResults); 113 searchResultsContainer.parentNode.appendChild(button); 114 return button; 115}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.