/** * Myext main content script run in all frames * * Copyright (C) 2021 Wojtek Kosior * * Dual-licensed under: * - 0BSD license * - GPLv3 or (at your option) any later version */ "use strict"; (() => { const handle_page_actions = window.handle_page_actions; var url_re = /^([^#]*)((#[^#]*)(#.*)?)?$/; var match = url_re.exec(document.URL); var base_url = match[1]; var first_target = match[3]; var second_target = match[4]; var block = true; if (first_target !== undefined && first_target === "#myext-allow") { block = false; console.log(["allowing", document.URL]); if (second_target !== undefined) window.location.href = base_url + second_target; else history.replaceState(null, "", base_url); } else { console.log(["not allowing", document.URL]); } function handle_mutation(mutations, observer) { if (document.readyState === 'complete') { console.log("complete"); observer.disconnect(); return; } for (let mutation of mutations) { for (let node of mutation.addedNodes) { if (node.tagName === "SCRIPT") block_script(node); else sanitize_attributes(node); } } } function block_script(node) { console.log(node); /* * Disabling scripts this way allows them to still be relatively * easily accessed in case they contain some useful data. */ if (node.hasAttribute("type")) node.setAttribute("blocked-type", node.getAttribute("type")); node.setAttribute("type", "application/json"); } function sanitize_attributes(node) { if (node.attributes === undefined) return; /* * We have to do it in 2 loops, removing attribute modifies * our iterator */ let attr_names = []; for (let attr of node.attributes) { let attr_name = attr.localName; if (attr_name.startsWith("on")) attr_names.push(attr_name); } for (let attr_name of attr_names) { node.removeAttribute(attr_name); console.log("sanitized", attr_name); } } if (block) { var observer = new MutationObserver(handle_mutation); observer.observe(document.documentElement, { attributes: true, childList: true, subtree: true }); } handle_page_actions(); })();