Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'document' vs. 'content.document'

I'm trying to write a Firefox extension that adds elements to the loaded page. So far, I get the root element of the document via

var domBody = content.document.getElementsByTagName("BODY").item(0);

and create the new elements via

var newDiv = content.document.createElement("div");

and everything worked quite well, actually. But the problems came when I added a button with on onclick attribute. While the button is correctly displayed, I get an error. I already asked asked here, and the answer with document.createElement() (without content) works.

But if I remove the 'content.' everywhere, the real trouble starts. Firstly, domBody is null/undefined, no matter how I try to access it, e.g. document.body (And actually I add all elements _after_the document is fully loaded. At least I think so). And secondly, all other elements look differently. It's seem the style information, e.g., element.style.width="300px" are no longer considered.

In short, with 'content.document' everything looks good, but the button.onclick throws an error. with only 'document' the button works, but the elements are no longer correctly displayed. Does anybody see a solution for that.

like image 716
Christian Avatar asked Aug 15 '11 16:08

Christian


2 Answers

It should work fine if you use addEventListener [MDN] (at least this is what I used). I read somewhere (I will search for it) that you cannot attach event listener via properties when creating elements in chrome code.

You still should use content.document.createElement though:

 Page = function(...) {
   ...
 };

 Page.prototype = {
   ...
   addButton : function() {
     var b = content.document.createElement('button');
     b.addEventListener('click', function() { 
         alert('OnClick'); 
     }, false);
   },
   ...
 };

I would store a reference to content.document somewhere btw.

like image 111
Felix Kling Avatar answered Nov 08 '22 13:11

Felix Kling


The existing answer doesn't have a real explanation and there are too many comments already, so I'll add another answer. When you access the content document then you are not accessing it directly - for security reasons you access it through a wrapper that exposes only actual DOM methods/properties and hides anything that the page's JavaScript might have added. This has the side-effect that properties like onclick won't work (this is actually the first point in the list of limitations of XPCNativeWrapper). You should use addEventListener instead. This has the additional advantage that more than one event listener can coexist, e.g. the web page won't remove your event listener by setting onclick itself.

Side-note: your script executes in the browser window, so document is the XUL document containing the browser's user interface. There is no <body> element because XUL documents don't have one. And adding a button won't affect the page in the selected tab, only mess up the browser's user interface. The global variable content refers to the window object of the currently selected tab so that's your entry point if you want to work with it.

like image 21
Wladimir Palant Avatar answered Nov 08 '22 13:11

Wladimir Palant