26 lines (24 loc) · 882 B
 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};