// leaderboard.js โ leaderboard page logic document.addEventListener("DOMContentLoaded", () => { const currentPlayer = Storage.getPlayerName(); const body = document.getElementById("lb-body"); /** * Escape HTML special characters to prevent XSS. * @param {string} str - Raw user-provided string. * @returns {string} HTML-safe string. */ function escHtml(str) { return String(str) .replace(/&/g, "&") .replace(//g, ">"); } /** Render the leaderboard from localStorage data. */ function render() { const board = Storage.getLeaderboard(); body.innerHTML = ""; if (!board.length) { body.innerHTML = `
`; return; } const medals = ["๐ฅ", "๐ฅ", "๐ฅ"]; const scoreClasses = ["gold", "silver", "bronze"]; board.forEach((entry, index) => { const rank = index + 1; const isYou = entry.name === currentPlayer; const date = entry.date ? new Date(entry.date).toLocaleDateString("en-CH", { day: "2-digit", month: "short" }) : "โ"; const rounds = (entry.scores || []).join(" ยท ") || "โ"; const row = document.createElement("div"); row.className = `lb-row${rank <= 3 ? ` rank-${rank}` : ""}`; row.style.animationDelay = `${index * 0.05}s`; row.innerHTML = ` ${rank <= 3 ? `${medals[rank - 1]}` : rank} ${escHtml(entry.name)} ${entry.totalScore} `; body.appendChild(row); }); // Show the current player's latest score bar const latest = board.find((entry) => entry.name === currentPlayer); if (latest) { document.getElementById("your-bar").style.display = "flex"; document.getElementById("your-bar-name").textContent = latest.name; document.getElementById("your-bar-score").textContent = latest.totalScore; } } render(); });