Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save JenieX/878ce367124c12923d3f919d25004595 to your computer and use it in GitHub Desktop.
Save JenieX/878ce367124c12923d3f919d25004595 to your computer and use it in GitHub Desktop.
Lightweight beforescriptexecute / onbeforescriptexecute polyfill
(function(){
if("onbeforescriptexecute" in document) return; // Already natively supported
let scriptWatcher = new MutationObserver(mutations => {
for(let mutation of mutations){
for(let node of mutation.addedNodes){
if(node.tagName === "SCRIPT"){
let syntheticEvent = new CustomEvent("beforescriptexecute", {
detail: node,
cancelable: true
})
// .dispatchEvent will execute the event synchrously,
// and return false if .preventDefault() is called
if(!document.dispatchEvent(syntheticEvent)){
node.remove();
}
}
}
}
})
scriptWatcher.observe(document, {
childList: true,
subtree: true
})
})()
document.addEventListener("beforescriptexecute", event => {
// There's no efficient way to set event.target
// Other polyfills try to accomplish this through hacky means like
// replacing the addEventListener prototype.
// Instead, we pass the element through the sanctioned event.details property.
//
// So if the event came from our polyfill, our target will be in event.details.
// If it's a native event, it will be in event.target
// Nice, clean, simple.
let script = event.details || event.target;
if(script.textContent.contains("function dontExecuteThisFunction(please)")){
event.preventDefault();
// Now the script won't execute.
// Use document.createElement("script") to inject replacement script here, if you want.
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment