title: Concurrency with Firefox add-on script and content script
body: <p>As I was writing a Firefox add-on using the <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/dev-guide/welcome.html" rel="nofollow">Add-on SDK</a>, I noticed that the add-on code and the content script code block the execution of each other. Furthermore, the add-on code seems even to block the interaction with other Firefox windows (not just tabs).</p>
  
  <p><strong>What is the concurrency/process model of Firefox add-ons?</strong></p>
  
  <p><strong>Is it possible to run add-on code and content script code concurrently without cooperative multithreading (a la timers)?</strong></p>
  
  <p><strong>How many times is the add-on code loaded? Once per window? Once per tab? Once?</strong></p>
  
  <p>The <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/dev-guide/addon-development/web-content.html" rel="nofollow">documentation</a> states:</p>
  
  <blockquote>
    <p>The Mozilla platform is moving towards a model in which it uses
    separate processes to display the UI, handle web content, and execute
    add-ons. The main add-on code will run in the add-on process and will
    not have direct access to any web content.</p>
  </blockquote>
  
  <p>So I hope that in the future that they are indeed separate processes that will not interfere with each other, but that doesn't seem to be the case now.</p>
  
  <hr>
  
  <p><strong>Update:</strong></p>
  
  <p>I have tried using a page-worker from the add-on code, but unfortunately that still blocks the content script (as well as all other javascript). I also tried using a web worker in the page-worker, but I get the following error when calling the web worker's postMessage function.</p>
  
  <blockquote>
    <p>TypeError: worker.postMessage is not a function</p>
  </blockquote>
  
  <p>I also tried creating an iframe in the page-worker and then creating a web worker in the iframe, but unfortunately I cannot use window.addEventListener from the page-worker. I get the following error:</p>
  
  <blockquote>
    <p>TypeError: window.addEventMessage is not a function</p>
  </blockquote>
  
  <p>Finally, I tried to inject script (via script element) into the page-worker page to create a web worker which does seem to work. Unfortunately, I cannot communicate with this web worker because I can only send messages to it via document.defaultView.postMessage.</p>
  
  <p>Oh the tangled webs I am weaving...</p>
  
  <p>content-script -> add-on -> page-worker -> iframe -> web worker -> my code</p>
  
  <hr>
  
  <p>I have included a simple example:</p>
  
  <p><strong>package.json</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>{
      "name": "test", 
      "author": "me", 
      "version": "0.1", 
      "fullName": "My Test Extension", 
      "homepage": "http://example.com", 
      "id": "jid1-FmgBxScAABzB2g", 
      "description": "My test extension"
  }
  </code></pre>
  
  <p><strong>lib/main.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>var data = require("self").data;
  var pageMod = require("page-mod");
  
  pageMod.PageMod({
      include: ["http://*", "https://*"],
      contentScriptWhen: "start",
      contentScriptFile: [data.url("content.js")],
      onAttach: function (worker) {
          worker.port.on("message", function (data) {
              // simulate an expensive operation with a busy loop
              var start = new Date();
              while (new Date() - start &lt; data.time);
              worker.port.emit("message", { text: 'done!' });
          });
      }
  });
  </code></pre>
  
  <p><strong>data/content.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>self.port.on("message", function (response) {
      alert(response.text);
  });
  
  // call a very expensive operation in the add-on code
  self.port.emit("message", { time: 10000 });
  </code></pre>