Reputation: 39
This MutationObserver Wrapper should be able to provide developers with any changes that have been made in the DOM for security reasons.
I need a simple way to create a wrapper for MutationObserver. I just want to be informed when a MutationObserver was created on the page. Then I want to make sure the code runs before all other codes so that I can put it in an extension.
This is what I tried:
const dump = console.log.bind(console);
class Observer
{
static started = false
static jacked = {}
static start()
{
Observer.started = true;
Observer.hijack( MutationObserver, function constructor()
{
alert("CAREFUL!! - MutationObserver is running here!");
return (Observer.jacked.MutationObserver).constructor.apply(this, [...arguments]);
});
// if (!Observer.fixes[document.domain])
// {
// dump("not listining on: "+document.domain);
// return;
// };
//
// Observer.fixes[document.domain]()
}
static hijack(target, impose)
{
let waiting = setInterval(()=>
{
if ((typeof target.prototype) !== "object"){ return };
if ((typeof target.prototype.constructor) !== "function"){ return };
clearInterval(waiting);
let name = target.prototype.constructor.name;
dump("hijacking: "+name);
Observer.jacked[name] = target;
Object.defineProperty(target.prototype, "constructor", {writable:false, configurable:false, enumerable:false, value:impose});
},0);
}
let waiting = setInterval(() =>
{
let exists = ((typeof MutationObserver) !== "undefined");
if ( !exists )
{
console.log("observer waiting for `MutationObserver`");
return
};
if ( Observer.started )
{
clearInterval(waiting);
console.log("observer already started .. exiting");
return
};
clearInterval(waiting);
Observer.start();
}, 0);
Upvotes: 0
Views: 187
Reputation: 449
Try something like this, however, be aware of what globalThis
refers to in your extension:
const jacked = {};
jacked.MutationObserver = globalThis.MutationObserver;
delete globalThis.MutationObserver;
globalThis.MutationObserver = (class MutationObserver
{
constructor()
{
console.log("jacked");
}
observe()
{
console.log("busy");
}
});
after running the above, anywhere, like in a function, you can test if your wrapper-test works like this:
let watcher = (new MutationObserver(function(){}));
watcher.observe();
You can use jacked
to resume normal operation inside your supplementary class constructor
by returning a new jacked.MutationObserver
.
Upvotes: 1