/** * @source: ./script.js (originally from araa-search on Github) * * @licstart The following is the entire license notice for the * JavaScript code in this page. * * Copyright (C) 2023 Extravi * * The JavaScript code in this page is free software: you can * redistribute it and/or modify it under the terms of the GNU Affero * General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. * * The code is distributed WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * As additional permission under GNU Affero General Public License * section 7, you may distribute non-source (e.g., minimized or compacted) * forms of that code without the copy of the GNU Affero General Public * License normally required by section 4, provided you include this * license notice and a URL through which recipients can access the * Corresponding Source. * * @licend The above is the entire license notice * for the JavaScript code in this page. */ // Removes the 'Apply Settings' button for Javascript users, // since changing any of the elements causes the settings to apply // automatically. let resultsSave = document.querySelector(".results-save"); if (resultsSave != null) { resultsSave.style.display = "none"; } const searchInput = document.getElementById('search-input'); const searchWrapper = document.querySelectorAll('.wrapper, .wrapper-results')[0]; const resultsWrapper = document.querySelector('.autocomplete'); // const clearSearch = document.querySelector("#clearSearch"); async function getSuggestions(query) { try { const params = new URLSearchParams({ "q": query }).toString(); const response = await fetch(`/suggestions?${params}`); const data = await response.json(); return data[1]; // Return only the array of suggestion strings } catch (error) { console.error(error); } } let currentIndex = -1; // Keep track of the currently selected suggestion let results = []; searchInput.addEventListener('input', async () => { let input = searchInput.value; if (input.length) { results = await getSuggestions(input); } renderResults(results); currentIndex = -1; // Reset index when we return new results }); searchInput.addEventListener("focus", async () => { let input = searchInput.value; if (results.length === 0 && input.length != 0) { results = await getSuggestions(input); } renderResults(results); }) // clearSearch.style.visibility = "visible"; // Only show the clear search button for JS users. // clearSearch.addEventListener("click", () => { // searchInput.value = ""; // searchInput.focus(); // }) searchInput.addEventListener('keydown', (event) => { if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'Tab') { event.preventDefault(); // Prevent the default behavior, such as moving the cursor // Find the currently selected suggestion element const selectedSuggestion = resultsWrapper.querySelector('.selected'); if (selectedSuggestion) { selectedSuggestion.classList.remove('selected'); // Deselect the currently selected suggestion } // Increment current index when ArrowUp is pressed otherwise hen Tab OR ArrowDown decrement if (event.key === 'ArrowUp') { currentIndex--; } else { currentIndex++; } // Wrap around the index if it goes out of bounds if (currentIndex < 0) { currentIndex = resultsWrapper.querySelectorAll('li').length - 1; } else if (currentIndex >= resultsWrapper.querySelectorAll('li').length) { currentIndex = 0; } // Select the new suggestion resultsWrapper.querySelectorAll('li')[currentIndex].classList.add('selected'); // Update the value of the search input searchInput.value = resultsWrapper.querySelectorAll('li')[currentIndex].textContent; } }); // Default to the currently selected type or fallback to 'text' let selectedType = document.querySelector('.search-active')?.value || 'text'; // Function to render results function renderResults(results) { if (!results || !results.length || !searchInput.value) { searchWrapper.classList.remove('show'); return; } let content = ''; results.forEach((item) => { content += `