mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
Fix copy-code buttons on /tutorial
This commit is contained in:
parent
d87d5e39c8
commit
f128ea3644
2 changed files with 132 additions and 108 deletions
|
@ -1,124 +1,147 @@
|
||||||
(() => {
|
(() => {
|
||||||
let sidebar = document.getElementById("sidebar-nav");
|
let sidebar = document.getElementById("sidebar-nav");
|
||||||
let searchBox = document.getElementById("module-search");
|
let searchBox = document.getElementById("module-search");
|
||||||
|
|
||||||
function search() {
|
if (searchBox != null) {
|
||||||
let text = searchBox.value.toLowerCase(); // Search is case-insensitive.
|
function search() {
|
||||||
|
let text = searchBox.value.toLowerCase(); // Search is case-insensitive.
|
||||||
|
|
||||||
if (text === "") {
|
if (text === "") {
|
||||||
// Un-hide everything
|
// Un-hide everything
|
||||||
sidebar.querySelectorAll(".sidebar-entry a").forEach((entry) => entry.classList.remove("hidden"));
|
sidebar
|
||||||
|
.querySelectorAll(".sidebar-entry a")
|
||||||
|
.forEach((entry) => entry.classList.remove("hidden"));
|
||||||
|
|
||||||
// Re-hide all the sub-entries except for those of the current module
|
// Re-hide all the sub-entries except for those of the current module
|
||||||
let currentModuleName = document.querySelector('.module-name').textContent;
|
let currentModuleName =
|
||||||
|
document.querySelector(".module-name").textContent;
|
||||||
|
|
||||||
sidebar.querySelectorAll(".sidebar-entry").forEach((entry) => {
|
sidebar.querySelectorAll(".sidebar-entry").forEach((entry) => {
|
||||||
let entryName = entry.querySelector('.sidebar-module-link').textContent;
|
let entryName = entry.querySelector(
|
||||||
if (currentModuleName === entryName) {
|
".sidebar-module-link"
|
||||||
entry.firstChild.classList.add("active");
|
).textContent;
|
||||||
return;
|
if (currentModuleName === entryName) {
|
||||||
};
|
entry.firstChild.classList.add("active");
|
||||||
entry.querySelectorAll(".sidebar-sub-entries a").forEach((subEntry) => subEntry.classList.add("hidden"));
|
return;
|
||||||
})
|
}
|
||||||
} else {
|
entry
|
||||||
// First, show/hide all the sub-entries within each module (top-level functions etc.)
|
.querySelectorAll(".sidebar-sub-entries a")
|
||||||
sidebar.querySelectorAll(".sidebar-sub-entries a").forEach((entry) => {
|
.forEach((subEntry) =>
|
||||||
if (entry.textContent.toLowerCase().includes(text)) {
|
subEntry.classList.add("hidden")
|
||||||
entry.classList.remove("hidden");
|
);
|
||||||
} else {
|
});
|
||||||
entry.classList.add("hidden");
|
} else {
|
||||||
|
// First, show/hide all the sub-entries within each module (top-level functions etc.)
|
||||||
|
sidebar
|
||||||
|
.querySelectorAll(".sidebar-sub-entries a")
|
||||||
|
.forEach((entry) => {
|
||||||
|
if (entry.textContent.toLowerCase().includes(text)) {
|
||||||
|
entry.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
entry.classList.add("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then, show/hide modules based on whether they match, or any of their sub-entries matched
|
||||||
|
sidebar
|
||||||
|
.querySelectorAll(".sidebar-module-link")
|
||||||
|
.forEach((entry) => {
|
||||||
|
if (
|
||||||
|
entry.textContent.toLowerCase().includes(text) ||
|
||||||
|
entry.parentNode.querySelectorAll(
|
||||||
|
".sidebar-sub-entries a:not(.hidden)"
|
||||||
|
).length > 0
|
||||||
|
) {
|
||||||
|
entry.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
entry.classList.add("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Then, show/hide modules based on whether they match, or any of their sub-entries matched
|
searchBox.addEventListener("input", search);
|
||||||
sidebar.querySelectorAll(".sidebar-module-link").forEach((entry) => {
|
|
||||||
if (entry.textContent.toLowerCase().includes(text) || entry.parentNode.querySelectorAll(".sidebar-sub-entries a:not(.hidden)").length > 0) {
|
|
||||||
entry.classList.remove("hidden");
|
|
||||||
} else {
|
|
||||||
entry.classList.add("hidden");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
searchBox.addEventListener("input", search);
|
search();
|
||||||
|
|
||||||
search();
|
// Capture '/' keypress for quick search
|
||||||
|
window.addEventListener("keyup", (e) => {
|
||||||
|
if (e.key === "s" && document.activeElement !== searchBox) {
|
||||||
|
e.preventDefault;
|
||||||
|
searchBox.focus();
|
||||||
|
searchBox.value = "";
|
||||||
|
}
|
||||||
|
|
||||||
// Capture '/' keypress for quick search
|
if (e.key === "Escape" && document.activeElement === searchBox) {
|
||||||
window.addEventListener("keyup", (e) => {
|
e.preventDefault;
|
||||||
if (e.key === "s" && document.activeElement !== searchBox) {
|
|
||||||
e.preventDefault;
|
// De-focus input box
|
||||||
searchBox.focus();
|
searchBox.blur();
|
||||||
searchBox.value = "";
|
|
||||||
|
// Reset sidebar state
|
||||||
|
search();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.key === "Escape" && document.activeElement === searchBox) {
|
const isTouchSupported = () => {
|
||||||
e.preventDefault;
|
try {
|
||||||
|
document.createEvent("TouchEvent");
|
||||||
// De-focus input box
|
return true;
|
||||||
searchBox.blur();
|
} catch (e) {
|
||||||
|
return false;
|
||||||
// Reset sidebar state
|
|
||||||
search();
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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", () => {
|
// 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";
|
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";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -2026,3 +2026,4 @@ Here are various Roc expressions involving operators, and what they desugar to.
|
||||||
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
<script type="text/javascript" src="/builtins/search.js" defer></script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue