// ==UserScript==
// @name        Decode Cloudflare-encoded email addresses
// @namespace   https://codeberg.org/smege1001/cf_email_decoder
// @match       *://*/*
// @grant       none
// @version     1.2.2
// @author      smege1001
// ==/UserScript==

/**
* @license CC0-1.0
**/

const emailprotectionURLHashRegex = /\/cdn-cgi\/l\/email-protection#([aA0-fF9]*)/;
const emailprotectionURLNoHashRegex = /\/cdn-cgi\/l\/email-protection/; //hash is stored on data-cfemail

function decodeEmail(hash) { //cloudflare email address decoder
    var hashArray = []; //split the hash into bytes
    for (var hAIndex = 0; hAIndex < hash.length; hAIndex += 2) {
	hashArray.push(parseInt(hash.substring(hAIndex, hAIndex + 2), 16));
    }
    
    var decoded = "";
    var key = hashArray[0]; //get the decode key

    for (var index = 1; index < hashArray.length; index++) {
	decoded += String.fromCharCode(hashArray[index] ^ key);
    }
    return decoded;
}

var links = document.querySelectorAll("a"); //get all the links

for (var linksIndex = 0; linksIndex < links.length; linksIndex++) {
    var link = links[linksIndex];
    if (emailprotectionURLHashRegex.test(link.href)) {
	var hash = link.href.match(emailprotectionURLHashRegex)[1];
	var decodedEmail = decodeEmail(hash);
	
	link.href = "mailto:" + decodedEmail; //replace the stupid email protection with just a mailto link

	if (link.getElementsByClassName("__cf_email__").length > 0) {
	    var linkChild = link.getElementsByClassName("__cf_email__")[0];
	    linkChild.innerText = decodedEmail;

	    linkChild.removeAttribute("data-cfemail");
	    linkChild.classList.remove("__cf_email__");
	    
	    if (linkChild.getAttribute("class") == "") linkChild.removeAttribute("class");
	}
    } else if (emailprotectionURLNoHashRegex.test(link.href) && link.hasAttribute("data-cfemail")) {
	var hash = link.getAttribute("data-cfemail");
	var decodedEmail = decodeEmail(hash);
	
	link.href = "mailto:" + decodedEmail;
	link.innerText = decodedEmail; //the inner text is just [email protected]
	
	//remove the useless attributes
	link.removeAttribute("data-cfemail");
	link.classList.remove("__cf_email__");

	if (link.getAttribute("class") == "") link.removeAttribute("class");
    }
}