Addon SDK - context-menu and page-mod workers

firefox-addon-sdk, javascript

Solution

Ran into this too. The Worker objects seem to stick around for some past pages (and reused when going Back and Forward in history). The solution is to listen to the `pagehide` and `pageshow` events so as to only keep the currently shown workers in the array:

var pageMod = require("sdk/page-mod");
var array = require('sdk/util/array');

var pageWorkers = [];
pageMod.PageMod({
  onAttach: function(worker) {
      array.add(pageWorkers, worker);
      worker.on('pageshow', function() { array.add(pageWorkers, this); });
      worker.on('pagehide', function() { array.remove(pageWorkers, this); });
      worker.on('detach', function() { array.remove(pageWorkers, this); });
      // do other work.
  }
});

Note that `array.add` function takes care of not adding duplicates.

Problem

I have been working on a context-menu that communicates with a page mod and come up against an issue. I am able to send a communication with right click to the page / tab in view as long as I do not refresh the page. When I refresh the page a new worker is created and the context menu cannot communicate with the worker. I now have two identical workers but it is like the old one has expired. That means this loop in onMessage: does not work because it picks up the first worker. ``` for (index = 0; index < workers.length; index += 1) { if (workers[index].tab.index === tabs.activeTab.index) { workers[index].port.emit("rightClick", string, ss.storage.product); } } ``` I have been looking to remove the old worker on refresh but there seems to be no option to do so. Am I fundamentally missing something about the handling of workers? The error I receive is: Error: The page is currently hidden and can no longer be used until it is visible again. This is consistent with the fact that as far as the worker is concerned I am now looking at a new page in the same tab. I thought worker.on('detach', function(){}) was supposed to handle this but it seems this is only on the closing of the tab. Any advice would be appreciated. added OK after a little break I decided to use the detachWorker function recommended elsewhere for detach. I placed it at the top of my pageMod object as below ``` // Clean up duplicate worker for (index in workers) { if(workers[index].url === worker.url && workers[index].tab.index === worker.tab.index) { detachWorker(workers[index], workers); } } ``` This fixes the issue (for now) although I don't think it is the correct approach. Any advances on a solution :).

Original source