How to override JavaScript function from Firefox extension?

I am trying to intercept document.write calls for all pages. Setting up interception within the page by introducing a script like

function overrideDocWrite() { alert("Override called"); document.write = function(w) { return function(s) { alert("special dom"); w.call(this, wrapString(s)); }; }(document.write); alert("Override finished"); } 

It just works, but I would like my extension to set up interception for each document object from within the extension. I could not find a way to do this. I tried to listen to the “download” event and set up the capture there, but this also fails. How to intercept calls to doc.write from the extension?

I have made some progress:

 var myExtension = { init: function() { var appcontent = document.getElementById("appcontent"); // browser if (appcontent) appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad, true); }, onPageLoad: function(aEvent) { var doc = aEvent.originalTarget; // doc is document that triggered "onload" event // do something with the loaded page. // doc.location is a Location object (see below for a link). // You can use it to make your code executed on certain pages only. alert("Override called"); alert(doc); alert(doc.write); alert(doc.wrappedJSObject); alert(doc.wrappedJSObject.write); doc.wrappedJSObject.write = function(w) { return function(s) { alert("special dom"); w.call(this, "(" + s + ")"); }; }(doc.write); alert("Override finished"); } } 

This seems to work, but DOMContentLoaded is the wrong event for the job because it fires too late! Is there an early event to listen to?

+4
source share
2 answers

Repetition of the question! I got an answer. Here is a sample code:

 const os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); os.addObserver({ observe : function(aWindow, aTopic, aData) { if (aWindow instanceof Ci.nsIDOMWindow && aTopic == 'content-document-global-created') { aWindow.wrappedJSObject.myfunction = function(){ // Do some stuff . . . } } } }, 'content-document-global-created', false); 

The same applies to a document with a document element inserted with a gecko 2.0 element.

+3
source

JavaScript uses a prototype inheritance system, instead of having classes, objects have prototypes. Prototypes are real objects that are used as a reference to other objects to inherit methods and attributes.

A better strategy would be to override the write method in the prototype "document" (which for an HTML document is HTMLDocument). This should effectively wrap the method for all instances of the “document” inside the pages loaded into the browser, since they all use the same prototype.

Instead

 document.write = function() { ... } 

try something like this:

 HTMLDocument.prototype.write= function() { ... } 

UPDATE: This doesn't seem as easy as I originally thought, it doesn't seem to work on the first try.

0
source

Source: https://habr.com/ru/post/1311474/


All Articles