views:

109

answers:

2

I'm writing a Firefox extension. The extension replaces certain words on the page with other words. Here's the basic code I'm using:

function startup() {
    gBrowser.addEventListener("load", pageLoad, true);
}

function pageLoad(event) {
    if (event.originalTarget instanceof HTMLDocument) {
     var ht = content.document.body.innerHTML;
     ht = ht.replace(/\bthe\b/g,"el");
     content.document.body.innerHTML = ht;
    }
}

The problem is that this code is causing an endless loop. When I set the innerHTML property of the body, it sends another load event, which causes the endless loop.

How can I modify the page when it loads without causing the page load event to fire again?

A: 

Would having a div or span tag immediately inside of your body tag be an option? Then you could just update the innerHTML of that element, and not the entire body...

AJ
+1  A: 

You could use the following code to check if it has already been run before.

var loaded = false;

function pageLoad(event) {
    if (!loaded) {
        if (event.originalTarget instanceof HTMLDocument) {
            var ht = content.document.body.innerHTML;
            ht = ht.replace(/\bthe\b/g,"el");
            content.document.body.innerHTML = ht;
        }
        loaded = true;
    }
}

Alternatively, if you wanted to keep the loaded variable out of global scope, you could use a closure:

var pageLoad = (function () {
  var loaded = false;
  return function(event) {
    if (!loaded) {
        if (event.originalTarget instanceof HTMLDocument) {
            var ht = content.document.body.innerHTML;
            ht = ht.replace(/\bthe\b/g,"el");
            content.document.body.innerHTML = ht;
        }
        loaded = true;
    }
  }
}();

The outer function gets executed immediately and returns the inner function which will have visibility of the loaded variable due to closure.

Jonathan Fingland