95 lines
2.7 KiB
JavaScript
95 lines
2.7 KiB
JavaScript
|
|
(function () {
|
||
|
|
const root = document.querySelector("[data-api-docs]");
|
||
|
|
if (!root) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const panels = Array.from(root.querySelectorAll("[data-doc-panel]"));
|
||
|
|
const navLinks = Array.from(root.querySelectorAll("[data-doc-link]"));
|
||
|
|
const DEFAULT = "home";
|
||
|
|
|
||
|
|
function activate(name, focus) {
|
||
|
|
let matched = false;
|
||
|
|
panels.forEach((panel) => {
|
||
|
|
const on = panel.dataset.docPanel === name;
|
||
|
|
panel.classList.toggle("is-active", on);
|
||
|
|
if (on) {
|
||
|
|
matched = true;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
if (!matched) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
root.querySelectorAll(".api-nav-link").forEach((link) => {
|
||
|
|
link.classList.toggle(
|
||
|
|
"is-active",
|
||
|
|
link.getAttribute("href") === "#" + name
|
||
|
|
);
|
||
|
|
});
|
||
|
|
if (focus) {
|
||
|
|
const panel = root.querySelector('[data-doc-panel="' + name + '"]');
|
||
|
|
if (panel) {
|
||
|
|
panel.focus({ preventScroll: true });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Resolve the current hash to a panel. The hash can point at a panel id
|
||
|
|
// (e.g. #endpoints) or at any element inside a panel (e.g. #ep-upload),
|
||
|
|
// letting FAQ answers deep-link straight into the reference.
|
||
|
|
function resolveHash(focus) {
|
||
|
|
const id = (location.hash || "").slice(1);
|
||
|
|
if (!id) {
|
||
|
|
activate(DEFAULT, focus);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const target = document.getElementById(id);
|
||
|
|
if (!target) {
|
||
|
|
activate(DEFAULT, focus);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const panel = target.closest("[data-doc-panel]");
|
||
|
|
const name = panel ? panel.dataset.docPanel : DEFAULT;
|
||
|
|
activate(name, focus && target === panel);
|
||
|
|
if (panel && target !== panel) {
|
||
|
|
// Scroll the deep-linked element into view once its panel is visible.
|
||
|
|
window.requestAnimationFrame(() => {
|
||
|
|
target.scrollIntoView({ block: "start", behavior: "smooth" });
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
window.addEventListener("hashchange", () => resolveHash(true));
|
||
|
|
|
||
|
|
navLinks.forEach((link) => {
|
||
|
|
link.addEventListener("click", () => {
|
||
|
|
// hashchange handles activation; this keeps top-level nav clicks snappy.
|
||
|
|
if (link.getAttribute("href") === location.hash) {
|
||
|
|
resolveHash(true);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// Add a copy button to every code block.
|
||
|
|
root.querySelectorAll(".code-block").forEach((block) => {
|
||
|
|
const pre = block.querySelector("pre");
|
||
|
|
if (!pre) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const button = document.createElement("button");
|
||
|
|
button.type = "button";
|
||
|
|
button.className = "copy-btn";
|
||
|
|
button.textContent = "Copy";
|
||
|
|
button.setAttribute("aria-label", "Copy code");
|
||
|
|
button.addEventListener("click", () => {
|
||
|
|
window.Warpbox.copyText(pre.innerText.trim(), button, "Copied");
|
||
|
|
});
|
||
|
|
block.appendChild(button);
|
||
|
|
});
|
||
|
|
|
||
|
|
resolveHash(false);
|
||
|
|
})();
|