I'm working on a minimal Firefox extension that loads a web page into an XUL iframe. (I also tried the html:iframe
, but met identical results.) The page may take some time to load completely - and I'm trying to receive the DOMContentLoaded
event, which should come before the load
event.
(The main reason being that I'm trying to inject a CSS stylesheet, and this should be done immediately after the DOMContentLoaded event, instead of waiting and having the page appear "unstyled" until the load event. However, this will be used for other reasons as well, so CSS-specific alternatives aren't a viable work-around.)
However, so far, I'm only able to receive the load
event - and not the DOMContentLoaded
nor the readyState
events.
The issue should be easily reproducible using the below XUL, and simply entering the path to the XUL in the Firefox location bar given its chrome://
URL (similar to this):
<?xml version="1.0"?>
<!DOCTYPE window>
<window xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript">
window.addEventListener("DOMContentLoaded", function(event){
try{
var outElem = document.getElementById("out");
var out = function(s){
outElem.value += s + "\n";
};
var frameTest = document.getElementById("iframe-test");
out("start: " + frameTest.contentDocument.readyState);
frameTest.addEventListener("DOMContentLoaded",
function(e){
out("DOMContentLoaded! " + e);
},
true);
frameTest.addEventListener("readystatechange",
function(e){
out("readystatechange: " + e);
},
true);
frameTest.addEventListener("load",
function(e){
out("load: " + e + ", state: " + frameTest.contentDocument.readyState);
},
true);
out("all listeners registered, frame location: " + frameTest.contentWindow.location + ", state: " + frameTest.contentDocument.readyState);
}catch(e){
alert(e);
}
}, true);
</script>
<iframe id="iframe-test" type="content" src="http://www.google.com" height="400" width="400"/>
<textbox id="out" rows="10" cols="80" multiline="true"/>
</window>
The output I'm receiving in the debug text box is:
start: uninitialized
all listeners registered, frame location: about:blank, state: uninitialized
load: [object Event], state: complete
I can't figure out why I don't receive any DOMContentLoaded!
or readystatechange:
outputs.
Another minimal example that also doesn't work is available at https://gist.github.com/2985342.
Pages I've already referenced include:
- In XUL, how do I know a browser-tag has finished loading?
- Ways to circumvent the same-origin policy
- https://developer.mozilla.org/en/DOM/element.addEventListener
- https://developer.mozilla.org/en/DOM/DOM_event_reference
I've mentioned this on irc.mozilla.org/#extdev, and was only able to obtain a response of "Works for everyone else.", and "Best to use capturing listeners, though." - which is why I have the 3rd useCapture
argument set to true
in all the above addEventListener
calls (though I haven't noticed any difference yet with setting this to false or omitting it entirely).
I'm looking to do this "the right way", without resorting to polling on contentDocument.readyState
.
Update: This and other similar examples work as expected when sampled through the "Real-time XUL Editor" (part of https://addons.mozilla.org/en-US/firefox/addon/extension-developer/), for example - but not when loaded as a chrome://test/content/test.xul
file. Is it true that when loaded through the location bar, that there are restricted privileges, etc., that are causing this issue?