Skip to content

Instantly share code, notes, and snippets.

@johnpauljanecek
Last active July 17, 2022 08:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnpauljanecek/3be8e90c34707544bdcc3b08641da616 to your computer and use it in GitHub Desktop.
Save johnpauljanecek/3be8e90c34707544bdcc3b08641da616 to your computer and use it in GitHub Desktop.
Monkey Patching Javascript
(function () {
var patchedFuncts = {};
var exportedFuncts = {};
function generate_report(htmlElm) {
var report = [];
report.push("tagName",htmlElm.tagName);
var attributes =htmlElm.attributes;
if(attributes) {
for(let i = 0;i < attributes.length;i++) {
report.push(attributes[i].name,attributes[i].value);
}
}
return report;
}
function ancestors(obj) {
/* stolen from
https://gist.github.com/h2non/6dd79c4312d0b20ccc4a
*/
var hierarchy = [];
if (['boolean', 'number', 'string', 'undefined'].indexOf(typeof obj) !== -1 || obj === null) { // primitives types
obj = Object(obj);
} else if (typeof obj === 'function') {
hierarchy.push(
obj.name ||
(obj.toString().match(/function (\w*)/) ||
obj.toString().match(/\[object (\w*)\]/))[1] ||
'Anonymous Function'
);
obj = obj.prototype;
} else if (obj.toString() !== '[object Object]' && obj.prototype) { // fix Objects instances and IE issue
hierarchy.push(
obj.prototype.constructor.name ||
(obj.prototype.constructor.toString().match(/function (\w*)/) ||
obj.prototype.constructor.toString().match(/\[object (\w*)\]/))[1] ||
'Anonymous Function'
);
obj = obj.prototype;
} else if (!Object.getPrototypeOf(obj) && obj.constructor) {
hierarchy.push(
obj.constructor.name ||
(obj.constructor.toString().match(/function (\w*)/) ||
obj.constructor.toString().match(/\[object (\w*)\]/))[1] ||
'Anonymous Function'
)
}
while (obj = Object.getPrototypeOf(obj)) {
if (obj && obj.constructor) {
hierarchy.push(
obj.constructor.name ||
(obj.constructor.toString().match(/function (\w*)/) ||
obj.constructor.toString().match(/\[object (\w*)\]/))[1] ||
'Anonymous Function'
)
}
}
return hierarchy
}
function beforeHookFunct(originalThis,name,args) {
console.log("beforeHook : " + name);
console.log("this : " + originalThis);
console.log("args" + args);
}
function afterHookFunct(originalThis,name,args,result) {
}
function monkey_patch(object,methodName,beforeHook,afterHook) {
/*
object : to be hooked
methodName : name of hooked method - string
beforeHook : function which takes an array of args
afterHook : function which takes an array of args and result
*/
var oldFunct = object[methodName];
var newFunct = function() {
var originalThis = this;
var args = Array.from(arguments);
if(beforeHook) {
beforeHook(originalThis,methodName,args);
}
var result = oldFunct.apply(originalThis,arguments);
if(afterHook) {
afterHook(args,result);
}
return result;
}
object[methodName] = newFunct;
}
// Document.prototype.createElement
// https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
// monkey_patch(Document.prototype,"createElement",beforeHookFunct,null);
// Document.prototype.createDocumentFragment
//https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment
//monkey_patch(Document.prototype,"createDocumentFragment",beforeHookFunct,null);
// Node.prototype.appendChild
//https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
//monkey_patch(Node.prototype,"appendChild",beforeHookFunct,null);
exportedFuncts["generate_report"] = generate_report;
exportedFuncts["ancestors"] = ancestors;
exportedFuncts["monkey_patch"] = monkey_patch;
document.__monkeyFuncts = exportedFuncts;
(function () {
// Node.prototype.appendChild
//https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
//monkey_patch(Node.prototype,"appendChild",beforeHookFunct,null);
function beforeHook(originalThis,name,args) {
//appendChild(aChild);
var aChild = args[0];
console.log("-----Node.appendChild(aChild)-----");
console.log("this : " + JSON.stringify(generate_report(originalThis)));
console.log("aChild : " + JSON.stringify(generate_report(aChild)))
}
monkey_patch(Node.prototype,"appendChild",beforeHook,null);
})();
})()
(function () {
/*
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
createElement(tagName)
createElement(tagName, options)
https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
*/
console.log("monkey patch start");
var old_CreateElement = Document.prototype.createElement
function new_CreateElement() {
var args = Array.from(arguments);
console.log("Document.prototype.createElement : " + args)
return old_CreateElement.apply(this,arguments);
}
//Document.prototype.createElement = new_CreateElement;
/*
https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment
*/
var old_CreateDocumentFragment = Document.prototype.createDocumentFragment;
function new_CreateDocumentFragment() {
var args = Array.from(arguments);
console.log("Document.prototype.createDocumentFragment : " + args);
return old_CreateDocumentFragment.apply(this,arguments);
}
//Document.prototype.createDocumentFragment = new_CreateDocumentFragment;
/*
https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
*/
var old_AppedNode = Node.prototype.appendChild;
function new_AppendChild() {
var args = Array.from(arguments);
console.log("Node.prototype.appendChild : " + this + " args : " + args);
console.log("Constructor Name : " + this.constructor.name);
return old_AppedNode.apply(this,arguments);
}
// Node.prototype.appendChild = new_AppendChild;
console.log("monkey patch end")
return true;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment