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);
Comments