Search code examples
javascriptfirefox-addonfirefox-addon-sdk

pageMod attaching workers multiple times


I have encountered this issue while working on an extension. I am attaching a pageMod to the page based on tab ready event to modify the contents of the page, but when I reload the page, the worker seems to get attached one more time, so after 1 reload it loads 2 workers for the same url (no iframes), after 2 reloads it loads 3 workers, etc. Here's the initial code that I started with (I ripped it out of the larger block):

mod = null;   

tabs.on('ready', function(tab) {    
    mod = this.pageMod.PageMod({
        include: ["*"],
        contentScriptFile: ["resource://data/full_page.js"],
        attachTo: ["top", "frame", "existing"],
        onAttach: function(worker) {
            Logger.log('---------> worker.url is ' + worker.url);
        }
    });
}

I was able to remedy this somewhat by destroying the mod on every ready event by attaching this code at the very beginning of the ready event handler.

mod = null;   

tabs.on('ready', function(tab) {
    if (mod) {
        mod.destroy();
    }

    mod = this.pageMod.PageMod({
        include: ["*"],
        contentScriptFile: ["resource://data/full_page.js"],
        attachTo: ["top", "frame", "existing"],
        onAttach: function(worker) {
            Logger.log('---------> worker.url is ' + worker.url);
        }
    });
}

However, I still see that two workers get attached after the first reload, three after the second, etc. I made sure my listener got initialized only once. Anybody encountered this before? Am I not using it correctly? Thanks! Luka


Solution

  • No, you're not using it correctly. A pagemod only needs to be set up once. It automatically attaches on ready. The page mod you created is going attach to every new page (["*"]). And every time a new page loads, a new pagemod is created that attaches to every new tab...

    If you want to insert a content script into every page, just get rid of the on ready listener.

        mod = this.pageMod.PageMod({
            include: ["*"],
            contentScriptFile: ["./full_page.js"],
            attachTo: ["top", "frame", "existing"],
            onAttach: function(worker) {
                Logger.log('---------> worker.url is ' + worker.url);
            }
        });
    

    If you want to use the on ready listener for a specific tab, attach a script to the tab:

    tabs.on('ready', function(tab) {    
        var worker = tab.attach({
            contentScriptFile: ["./full_page.js"]
        });
        Logger.log('---------> worker.url is ' + worker.url);
    }