mirror of
https://github.com/NotAShelf/neovim-flake.git
synced 2025-01-29 20:49:48 +01:00
125 lines
4.1 KiB
JavaScript
125 lines
4.1 KiB
JavaScript
document.addEventListener("DOMContentLoaded", () => {
|
|
// The search widget should only be visible if we're in the options page. Else, we
|
|
// want it hidden.
|
|
if (window.location.pathname.endsWith("options.html")) {
|
|
console.log("Running script on options.html");
|
|
|
|
// Static
|
|
const searchBar = document.createElement("div");
|
|
searchBar.id = "search-bar";
|
|
searchBar.innerHTML = `
|
|
<input type="text" id="search-input" placeholder="Search options by name..." disabled />
|
|
`;
|
|
document.body.prepend(searchBar);
|
|
|
|
// Floating
|
|
const searchPopup = document.createElement("div");
|
|
searchPopup.id = "search-popup";
|
|
searchPopup.innerHTML = `
|
|
<div id="search-popup-content">
|
|
<input type="text" id="search-input-popup" placeholder="Search options..." />
|
|
<ul id="search-results-list"></ul>
|
|
</div
|
|
`;
|
|
searchPopup.classList.add("hidden");
|
|
document.body.appendChild(searchPopup);
|
|
|
|
// Focus the input on pop-up widget
|
|
searchBar.addEventListener("click", (event) => {
|
|
event.stopPropagation(); // also cancel clicks to get rid of that annoying cursor flicker
|
|
console.log("Search bar clicked!");
|
|
|
|
// Visibility
|
|
if (searchPopup.style.display === "block") {
|
|
searchPopup.style.display = "none";
|
|
} else {
|
|
searchPopup.style.display = "block";
|
|
document.getElementById("search-input-popup").focus();
|
|
}
|
|
});
|
|
|
|
// Ctrl+K opens the floating search widget
|
|
document.addEventListener("keydown", (event) => {
|
|
if (event.ctrlKey && event.key === "k") {
|
|
event.preventDefault();
|
|
console.log("Ctrl+K pressed!");
|
|
searchPopup.style.display = "block";
|
|
document.getElementById("search-input-popup").focus();
|
|
}
|
|
});
|
|
|
|
// Close the popup when clicking outside
|
|
document.addEventListener("click", (event) => {
|
|
if (
|
|
!searchPopup.contains(event.target) &&
|
|
event.target !== searchBar
|
|
) {
|
|
console.log("Click outside, hiding popup");
|
|
searchPopup.style.display = "none";
|
|
}
|
|
});
|
|
|
|
// Close the popup with Esc key
|
|
document.addEventListener("keydown", (event) => {
|
|
if (event.key === "Escape") {
|
|
console.log("Escape pressed!");
|
|
searchPopup.style.display = "none";
|
|
}
|
|
});
|
|
|
|
// Handle input
|
|
const searchInput = document.getElementById("search-input-popup");
|
|
const searchResultsList = document.getElementById(
|
|
"search-results-list",
|
|
);
|
|
const codeElements = document.querySelectorAll("code.option");
|
|
|
|
searchInput.addEventListener("input", (event) => {
|
|
const query = event.target.value.toLowerCase();
|
|
searchResultsList.innerHTML = ""; // clear previous
|
|
|
|
// Find matching
|
|
const matchingOptions = [];
|
|
codeElements.forEach((code) => {
|
|
const optionText = code.textContent;
|
|
if (optionText.toLowerCase().includes(query)) {
|
|
// Search should be case-insensitive, since chances are
|
|
// the user doesn't *actually* know what they're looking for.
|
|
const anchorId = code.closest("a").id;
|
|
matchingOptions.push({ text: optionText, id: anchorId });
|
|
}
|
|
});
|
|
|
|
// Limit the number of visible entries (e.g., show max 10 matches)
|
|
const maxVisibleResults = 10;
|
|
const resultsToShow = matchingOptions.slice(0, maxVisibleResults);
|
|
|
|
// Display matching
|
|
resultsToShow.forEach(({ text, id }) => {
|
|
const li = document.createElement("li");
|
|
li.textContent = text;
|
|
li.addEventListener("click", () => {
|
|
// Update the hash to the option name with a prefix
|
|
// e.g., #vim.enableEditorconfig -> #opt-vim.enableEditorconfig
|
|
const optionId = `opt-${text}`;
|
|
window.location.hash = `#${optionId}`;
|
|
searchPopup.style.display = "none";
|
|
|
|
const element = document.getElementById(id);
|
|
if (element) {
|
|
element.scrollIntoView({ behavior: "smooth" }); // doesn't really scroll very smoothly
|
|
}
|
|
});
|
|
searchResultsList.appendChild(li);
|
|
});
|
|
|
|
// If there are items > maxVisibleResults, show a "See More" option
|
|
if (matchingOptions.length > maxVisibleResults) {
|
|
const li = document.createElement("li");
|
|
li.textContent = `${matchingOptions.length - maxVisibleResults} more results...\nNarrow down your query to see them.`;
|
|
li.style.fontStyle = "italic";
|
|
searchResultsList.appendChild(li);
|
|
}
|
|
});
|
|
}
|
|
});
|