mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-22 22:15:02 +00:00
270 lines
8.5 KiB
JavaScript
270 lines
8.5 KiB
JavaScript
(() => {
|
|
let sidebar = document.getElementById("sidebar-nav");
|
|
|
|
if (sidebar != null) {
|
|
// Un-hide everything
|
|
sidebar
|
|
.querySelectorAll(".sidebar-entry a")
|
|
.forEach((entry) => entry.classList.remove("hidden"));
|
|
|
|
// Re-hide all the sub-entries except for those of the current module
|
|
let currentModuleName = document.querySelector(".module-name").textContent;
|
|
|
|
sidebar.querySelectorAll(".sidebar-entry").forEach((entry) => {
|
|
let entryName = entry.querySelector(".sidebar-module-link").textContent;
|
|
if (currentModuleName === entryName) {
|
|
entry.firstChild.classList.add("active");
|
|
return;
|
|
}
|
|
entry
|
|
.querySelectorAll(".sidebar-sub-entries a")
|
|
.forEach((subEntry) => subEntry.classList.add("hidden"));
|
|
});
|
|
}
|
|
|
|
let searchTypeAhead = document.getElementById("search-type-ahead");
|
|
let searchBox = document.getElementById("module-search");
|
|
let searchForm = document.getElementById("module-search-form");
|
|
let topSearchResultListItem = undefined;
|
|
|
|
// Hide the results whenever anyone clicks outside the search results.
|
|
window.addEventListener("click", function (event) {
|
|
if (!searchForm?.contains(event.target)) {
|
|
searchTypeAhead.classList.add("hidden");
|
|
}
|
|
});
|
|
|
|
if (searchBox != null) {
|
|
function searchKeyDown(event) {
|
|
switch (event.key) {
|
|
case "ArrowDown": {
|
|
event.preventDefault();
|
|
|
|
const focused = document.querySelector(
|
|
"#search-type-ahead > li:not([class*='hidden']) > a:focus",
|
|
);
|
|
|
|
// Find the next element to focus.
|
|
let nextToFocus = focused?.parentElement?.nextElementSibling;
|
|
|
|
while (
|
|
nextToFocus != null &&
|
|
nextToFocus.classList.contains("hidden")
|
|
) {
|
|
nextToFocus = nextToFocus.nextElementSibling;
|
|
}
|
|
|
|
if (nextToFocus == null) {
|
|
// If none of the links were focused, focus the first one.
|
|
// Also if we've reached the last one in the list, wrap around to the first.
|
|
document
|
|
.querySelector(
|
|
"#search-type-ahead > li:not([class*='hidden']) > a",
|
|
)
|
|
?.focus();
|
|
} else {
|
|
nextToFocus.querySelector("a").focus();
|
|
}
|
|
|
|
break;
|
|
}
|
|
case "ArrowUp": {
|
|
event.preventDefault();
|
|
|
|
const focused = document.querySelector(
|
|
"#search-type-ahead > li:not([class*='hidden']) > a:focus",
|
|
);
|
|
|
|
// Find the next element to focus.
|
|
let nextToFocus = focused?.parentElement?.previousElementSibling;
|
|
while (
|
|
nextToFocus != null &&
|
|
nextToFocus.classList.contains("hidden")
|
|
) {
|
|
nextToFocus = nextToFocus.previousElementSibling;
|
|
}
|
|
|
|
if (nextToFocus == null) {
|
|
// If none of the links were focused, or we're at the first one, focus the search box again.
|
|
searchBox?.focus();
|
|
} else {
|
|
// If one of the links was focused, focus the previous one
|
|
nextToFocus.querySelector("a").focus();
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
searchForm.addEventListener("keydown", searchKeyDown);
|
|
|
|
function search() {
|
|
topSearchResultListItem = undefined;
|
|
let text = searchBox.value.toLowerCase(); // Search is case-insensitive.
|
|
|
|
if (text === "") {
|
|
searchTypeAhead.classList.add("hidden");
|
|
} else {
|
|
let totalResults = 0;
|
|
// Firsttype-ahead-signature", show/hide all the sub-entries within each module (top-level functions etc.)
|
|
searchTypeAhead.querySelectorAll("li").forEach((entry) => {
|
|
const entryModule = entry
|
|
.querySelector(".type-ahead-module-name")
|
|
.textContent.toLowerCase();
|
|
const entryName = entry
|
|
.querySelector(".type-ahead-def-name")
|
|
.textContent.toLowerCase();
|
|
const entrySignature = entry
|
|
.querySelector(".type-ahead-signature")
|
|
?.textContent?.toLowerCase()
|
|
?.replace(/\s+/g, "");
|
|
|
|
const qualifiedEntryName = `${entryModule}.${entryName}`;
|
|
|
|
if (
|
|
qualifiedEntryName.includes(text) ||
|
|
entrySignature?.includes(text.replace(/\s+/g, ""))
|
|
) {
|
|
totalResults++;
|
|
entry.classList.remove("hidden");
|
|
if (topSearchResultListItem === undefined) {
|
|
topSearchResultListItem = entry;
|
|
}
|
|
} else {
|
|
entry.classList.add("hidden");
|
|
}
|
|
});
|
|
if (totalResults < 1) {
|
|
searchTypeAhead.classList.add("hidden");
|
|
} else {
|
|
searchTypeAhead.classList.remove("hidden");
|
|
}
|
|
}
|
|
}
|
|
|
|
searchBox.addEventListener("input", search);
|
|
|
|
search();
|
|
|
|
function searchSubmit(e) {
|
|
// pick the top result if the user submits search form
|
|
e.preventDefault();
|
|
if (topSearchResultListItem !== undefined) {
|
|
let topSearchResultListItemAnchor =
|
|
topSearchResultListItem.querySelector("a");
|
|
if (topSearchResultListItemAnchor !== null) {
|
|
topSearchResultListItemAnchor.click();
|
|
}
|
|
}
|
|
}
|
|
searchForm.addEventListener("submit", searchSubmit);
|
|
|
|
// Capture '/' keypress for quick search
|
|
window.addEventListener("keyup", (e) => {
|
|
if (e.key === "s" && document.activeElement !== searchBox) {
|
|
e.preventDefault();
|
|
searchBox.focus();
|
|
searchBox.value = "";
|
|
}
|
|
|
|
if (e.key === "Escape") {
|
|
if (document.activeElement === searchBox) {
|
|
// De-focus and clear input box
|
|
searchBox.value = "";
|
|
searchBox.blur();
|
|
} else {
|
|
// Hide the search results
|
|
searchTypeAhead.classList.add("hidden");
|
|
|
|
if (searchTypeAhead.contains(document.activeElement)) {
|
|
searchBox.focus();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
const isTouchSupported = () => {
|
|
try {
|
|
document.createEvent("TouchEvent");
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Select all <samp> elements that are children of <pre> elements
|
|
const codeBlocks = document.querySelectorAll("pre > samp");
|
|
|
|
// Iterate over each code block
|
|
codeBlocks.forEach((codeBlock) => {
|
|
// Create a "Copy" button
|
|
const copyButton = document.createElement("button");
|
|
copyButton.classList.add("copy-button");
|
|
copyButton.textContent = "Copy";
|
|
|
|
// Add event listener to copy button
|
|
copyButton.addEventListener("click", () => {
|
|
const codeText = codeBlock.innerText;
|
|
navigator.clipboard.writeText(codeText);
|
|
copyButton.textContent = "Copied!";
|
|
copyButton.classList.add("copy-button-copied");
|
|
copyButton.addEventListener("mouseleave", () => {
|
|
copyButton.textContent = "Copy";
|
|
copyButton.classList.remove("copy-button-copied");
|
|
});
|
|
});
|
|
|
|
// Create a container for the copy button and append it to the document
|
|
const buttonContainer = document.createElement("div");
|
|
buttonContainer.classList.add("button-container");
|
|
buttonContainer.appendChild(copyButton);
|
|
codeBlock.parentNode.insertBefore(buttonContainer, codeBlock);
|
|
|
|
// Hide the button container by default
|
|
buttonContainer.style.display = "none";
|
|
|
|
if (isTouchSupported()) {
|
|
// Show the button container on click for touch support (e.g. mobile)
|
|
document.addEventListener("click", (event) => {
|
|
if (event.target.closest("pre > samp") !== codeBlock) {
|
|
buttonContainer.style.display = "none";
|
|
} else {
|
|
buttonContainer.style.display = "block";
|
|
}
|
|
});
|
|
} else {
|
|
// Show the button container on hover for non-touch support (e.g. desktop)
|
|
codeBlock.parentNode.addEventListener("mouseenter", () => {
|
|
buttonContainer.style.display = "block";
|
|
});
|
|
|
|
codeBlock.parentNode.addEventListener("mouseleave", () => {
|
|
buttonContainer.style.display = "none";
|
|
});
|
|
}
|
|
});
|
|
})();
|
|
|
|
(() => {
|
|
let body = document.body;
|
|
const sidebarOpen = "sidebar-open";
|
|
const removeOpenClass = () => {
|
|
body.classList.remove(sidebarOpen);
|
|
document.body
|
|
.querySelector("main")
|
|
.removeEventListener("click", removeOpenClass);
|
|
};
|
|
Array.from(document.body.querySelectorAll(".menu-toggle")).forEach(
|
|
(menuToggle) => {
|
|
menuToggle.addEventListener("click", (e) => {
|
|
body.classList.toggle(sidebarOpen);
|
|
e.stopPropagation();
|
|
if (body.classList.contains(sidebarOpen)) {
|
|
document.body.addEventListener("click", removeOpenClass);
|
|
}
|
|
});
|
|
},
|
|
);
|
|
})();
|