pyc-kernel-lab / assets /js /shared.js
Allanatrix's picture
Publish PyC performance site
85928ca verified
Raw History Blame Contribute Delete
2.99 kB
export function byId(id) {
return document.getElementById(id);
}
export function formatNumber(value, digits) {
if (typeof value !== "number" || Number.isNaN(value)) {
return "-";
}
return value.toFixed(digits);
}
export function toSiteHref(path) {
if (!path) {
return "#";
}
if (/^https?:\/\//i.test(path)) {
return path;
}
return new URL(path, window.location.href).toString();
}
export async function fetchJson(path, init) {
const response = await fetch(path, init);
if (!response.ok) {
throw new Error(`Failed to fetch ${path}: ${response.status}`);
}
return await response.json();
}
export async function fetchText(path, init) {
const response = await fetch(path, init);
if (!response.ok) {
throw new Error(`Failed to fetch ${path}: ${response.status}`);
}
return await response.text();
}
export async function fetchJsonWithFallback(paths, init) {
let lastError = null;
for (const path of paths) {
try {
return await fetchJson(toSiteHref(path), init);
} catch (error) {
lastError = error;
}
}
throw lastError ?? new Error("No fetch paths succeeded.");
}
export function preferredTheme() {
try {
const stored = window.localStorage.getItem("pyc-theme");
if (stored === "light" || stored === "dark") {
return stored;
}
} catch (_error) {
}
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
return "dark";
}
return "light";
}
export function applyTheme(theme, button) {
const resolved = theme === "dark" ? "dark" : "light";
document.documentElement.setAttribute("data-theme", resolved);
if (button) {
button.textContent = resolved === "dark" ? "Light Mode" : "Dark Mode";
button.setAttribute("aria-pressed", resolved === "dark" ? "true" : "false");
}
}
export function initThemeToggle(buttonId = "theme-toggle") {
const button = byId(buttonId);
applyTheme(preferredTheme(), button);
if (!button) {
return;
}
button.addEventListener("click", () => {
const current = document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light";
const next = current === "dark" ? "light" : "dark";
applyTheme(next, button);
try {
window.localStorage.setItem("pyc-theme", next);
} catch (_error) {
}
});
}
export function setImageWithFallback(image, source, fallback) {
if (!image) {
return;
}
const fallbackHref = fallback ? toSiteHref(fallback) : null;
if (source) {
image.src = toSiteHref(source);
} else if (fallbackHref) {
image.src = fallbackHref;
}
if (fallbackHref) {
image.onerror = () => {
if (image.src !== fallbackHref) {
image.src = fallbackHref;
}
};
}
}