Vemonus Vemonus - 1 year ago 43
jQuery Question

How to dynamically change the ContentURL of a page-worker for Firefox Add-on?

I am working on a simple dictionary add-on that allows the user to highlight a word (by double-clicking on it), which will cause a popup displaying a dictionary definition of the word to appear.

I am having trouble dynamically changing the ContentURL of the page-worker that I am using so that I can access its DOM and scrape the definition from it.
I have tried both dynamically changing the URL of a single page-worker, as well as creating a page-worker each time a new word is selected, sending the information to the addon, then destroying the page-worker.

Here is my code(for the second idea):


$(window).dblclick(function() {
var selected = getSelected();
if (selected!="") {
var completedURL = "" + selected;


function getSelected() {
if (window.getSelection) {
return window.getSelection().toString();
} else if (document.selection) {
return document.selection.createRange().text;
return '';


var sendInformation = "var elements = document.querySelectorAll('div.def-set > div'); " +
"for (var i = 0; i < elements.length; i++) {" +
" postMessage(elements[i].textContent) " +
"}" +

function createPageWorker(URL){

contentScriptWhen: "ready",
contentScriptFile: [
contentURL: URL,
contentScript: sendInformation,
onMessage: "function(message){"+

If I were using my first idea, the line


would be replaced with the line

dictionaryReference.contentURL = completedURL;

to a page-worker "dictionaryReference" contained in my index.js file.

Please do not simply post links to MDN; I've read through all of the relevant documentation and it has not given me much guidance.

Answer Source

From (forgive me for posting the MDN docs ;-) ):

  • the add-on's main code, including "main.js" and other modules in "lib", can use the SDK high-level and low-level APIs, but can't access web content directly
  • content scripts can't use the SDK's APIs (no access to globals exports, require) but can access web content

It seems as though you are trying to access createPageWorker() from define.js, which seems to be a content script. This is forbidden by the separation of concerns. The way to communicate would be to use something like

self.port.emit("createPageWorker", URL);

in the content script, and listen to that message via

self.port.on("createPageWorker", function(URL) { 
    // do something here

in the add-on code (index.js or whatever).