1import { $$ } from "./dom.js";
2
3// Decode a Cloudflare-obfuscated email: each byte is XOR'd with the leading
4// key byte.
5const decode = (hex) => {
6 let out = "";
7 const key = parseInt(hex.slice(0, 2), 16);
8 for (let i = 2; i < hex.length; i += 2) {
9 out += String.fromCharCode(parseInt(hex.slice(i, i + 2), 16) ^ key);
10 }
11 return out;
12};
13
14/**
15 * Decode Cloudflare-obfuscated emails. Cloudflare's own decoder runs only on a
16 * full page load, so addresses injected by the router are decoded here.
17 */
18export const decodeCloudflareEmails = (root = document) => {
19 $$("[data-cfemail]", root).forEach((el) => {
20 const email = decode(el.dataset.cfemail);
21 el.textContent = email;
22 el.classList.remove("__cf_email__");
23 const link = el.closest('a[href*="email-protection"]') || (el.tagName === "A" ? el : null);
24 if (link) link.href = "mailto:" + email;
25 });
26};