var args = [ { domain: /^(.*\.)?facebook\.com$/, args: ['__tn__', '__xts__[0]'] }, { domain: /^(.*\.)?instagram\.com$/, args: ['igshid'] }, { domain: /^(.*\.)?youtube\.com$/, args: ['feature'] }, { domain: /^(.*\.)?repubblica\.it$/, args: ['ref'] }, { domain: /./, args: ['fbclid', 'gclid', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'refresh_ce'] } ]; function sanitizeUrl(node, url, list) { var changed; for (var i = 0; i < list.length; i++) { if (url.searchParams.has(list[i])) { changed = true; url.searchParams.delete(list[i]); } } if (changed) node.value = url.toString(); } function sanitizeNode(node) { if (node.tagName != 'A') return; var href = node.attributes['href']; if (!href) return; href = href.value; url = new URL(href, location.origin); if (url.protocol != 'http:' && url.protocol != 'https:') return; for (var i = 0; i < args.length; i++) if (url.hostname.match(args[i].domain)) sanitizeUrl(node.attributes['href'], url, args[i].args); } function walk(node) { // thanks to: http://is.gd/mwZp7E switch (node.nodeType) { case 1: // Node.ELEMENT_NODE sanitizeNode(node); case 9: // Node.DOCUMENT_NODE case 11: // Node.DOCUMENT_FRAGMENT_NODE var child = node.firstChild; while (child) { var next = child.nextSibling; walk(child); child = next; } break; } } // register a MutationObserver to handle DOM edits by client-side JS. new MutationObserver(function (mlist) { for (var i = 0; i < mlist.length; i++) walk(mlist[i].target); }).observe(document, { childList: true, subtree: true, attributes: true, attributeFilter: ['href'], }) walk(document.body);