mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
New docs template
This commit is contained in:
parent
8f2ff5158d
commit
11e736f3e8
3 changed files with 556 additions and 480 deletions
|
@ -1,231 +1,270 @@
|
|||
(() => {
|
||||
let sidebar = document.getElementById("sidebar-nav");
|
||||
let sidebar = document.getElementById("sidebar-nav");
|
||||
|
||||
if (sidebar != null) {
|
||||
// Un-hide everything
|
||||
sidebar
|
||||
.querySelectorAll(".sidebar-entry a")
|
||||
.forEach((entry) => entry.classList.remove("hidden"));
|
||||
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;
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
entry
|
||||
.querySelectorAll(".sidebar-sub-entries a")
|
||||
.forEach((subEntry) => subEntry.classList.add("hidden"));
|
||||
});
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let searchTypeAhead = document.getElementById("search-type-ahead");
|
||||
let searchBox = document.getElementById("module-search");
|
||||
let searchForm = document.getElementById("module-search-form");
|
||||
let topSearchResultListItem = undefined;
|
||||
searchForm.addEventListener("keydown", searchKeyDown);
|
||||
|
||||
// Hide the results whenever anyone clicks outside the search results.
|
||||
window.addEventListener("click", function(event) {
|
||||
if (!searchForm?.contains(event.target)) {
|
||||
searchTypeAhead.classList.add("hidden");
|
||||
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");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (searchBox != null) {
|
||||
function searchKeyDown(event) {
|
||||
switch (event.key) {
|
||||
case "ArrowDown": {
|
||||
event.preventDefault();
|
||||
searchBox.addEventListener("input", search);
|
||||
|
||||
const focused = document.querySelector("#search-type-ahead > li:not([class*='hidden']) > a:focus");
|
||||
search();
|
||||
|
||||
// Find the next element to focus.
|
||||
let nextToFocus = focused?.parentElement?.nextElementSibling;
|
||||
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);
|
||||
|
||||
while (nextToFocus != null && nextToFocus.classList.contains("hidden")) {
|
||||
nextToFocus = nextToFocus.nextElementSibling;
|
||||
}
|
||||
// Capture '/' keypress for quick search
|
||||
window.addEventListener("keyup", (e) => {
|
||||
if (e.key === "s" && document.activeElement !== searchBox) {
|
||||
e.preventDefault();
|
||||
searchBox.focus();
|
||||
searchBox.value = "";
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
if (searchTypeAhead.contains(document.activeElement)) {
|
||||
searchBox.focus();
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
})();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue