2020-04-29 08:37:43 +00:00
|
|
|
/**
|
|
|
|
* Remove all the IFRAMEs that are off-site or do not have a “src” attribute.
|
|
|
|
* These are typically used for ads and unwanted external content.
|
|
|
|
* navigation etc.
|
|
|
|
*
|
|
|
|
* IFRAMEs without a “src” attribute are also used for sandboxing untrusted
|
|
|
|
* content, e.g. on mailinator.com, but I have not yet found a way to
|
|
|
|
* distinguish between src-less IFRAMEs for ads and src-less IFRAMEs for
|
|
|
|
* “regular” content. Maybe try to guess based on the dimensions? Meh.
|
|
|
|
*
|
|
|
|
* @title rm IFRAMEs
|
|
|
|
*/
|
|
|
|
(function rmi() {
|
|
|
|
/* Create a new IFRAME to get a "clean" Window object, so we can use its
|
|
|
|
* console. Sometimes sites (e.g. Twitter) override console.log and even
|
|
|
|
* the entire console object. "delete console.log" or "delete console"
|
|
|
|
* does not always work, and messing with the prototype seemed more
|
|
|
|
* brittle than this. */
|
|
|
|
let console = (function () {
|
|
|
|
let iframe = document.getElementById('xxxJanConsole');
|
|
|
|
if (!iframe) {
|
|
|
|
iframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
|
|
|
|
iframe.id = 'xxxJanConsole';
|
|
|
|
iframe.style.display = 'none';
|
|
|
|
|
|
|
|
(document.body || document.documentElement).appendChild(iframe);
|
|
|
|
}
|
|
|
|
|
|
|
|
return iframe && iframe.contentWindow && iframe.contentWindow.console || {
|
|
|
|
log: function () {}
|
|
|
|
};
|
|
|
|
})();
|
|
|
|
|
|
|
|
/* Keep track of the HTMLDocument instances we have processed. */
|
|
|
|
let processed = new Set();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is the given node empty-ish? I.e., does it lack child elements and
|
|
|
|
* non-whitespace text?
|
|
|
|
*/
|
|
|
|
function isEmpty(node) {
|
|
|
|
return !node || (!node.childElementCount && (typeof node.textContent !== 'string' || node.textContent.trim() === ''));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The main function. */
|
|
|
|
(function execute(document) {
|
|
|
|
if (!document || typeof document.querySelectorAll !== 'function' || processed.has(document)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
processed.add(document);
|
|
|
|
|
|
|
|
/* Process all IFRAMEs. */
|
|
|
|
Array.from(document.querySelectorAll('iframe:not(#xxxJanConsole)')).forEach(iframe => {
|
|
|
|
let shouldDelete = false;
|
|
|
|
try {
|
|
|
|
shouldDelete = iframe.contentDocument === null || iframe.src === '';
|
|
|
|
} catch (e) {
|
|
|
|
shouldDelete = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldDelete) {
|
|
|
|
console.log('rm IFRAMEs: found suspicious IFRAME to delete: ', iframe);
|
|
|
|
let parentNode = iframe.parentNode;
|
|
|
|
iframe.remove();
|
|
|
|
|
|
|
|
while (parentNode && isEmpty(parentNode)) {
|
|
|
|
console.log('rm IFRAMEs: found empty parent node to delete: ', parentNode);
|
|
|
|
let oldParentNode = parentNode;
|
|
|
|
parentNode = parentNode.parentNode;
|
|
|
|
oldParentNode.remove();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
console.log('rm IFRAMEs: found non-suspicious IFRAME to recurse into: ', iframe);
|
|
|
|
execute(iframe.contentDocument);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})(document);
|
|
|
|
})();
|