1
votes

EDIT 3: Solution/fix found

Here's the SO thread that solved it for me: PageMod attaching worker to same URL multiple times

TLDR: If the page contains iFrames, it will attach a worker/content script to it which results in multiple content scripts attempting to run. Using attachTo: 'top' only attaches the script to the top level document and no iFrames.


I'm working on porting a simple Chrome extension I made, and I'm having a hard time with message passing for a Firefox addon. Here's what I have.

csScript.js

self.port.emit("url", getVideoUrl());

function getVideoUrl() {  
  return $('meta[itemprop=contentURL]').prop('content');
}

main.js

pageMod.PageMod({
  include: [URLs],
  exclude: [URLs],
  contentScriptFile: [data.url("jquery-2.1.1.min.js"),
                      data.url("csScript.js")],
  onAttach: function(worker) {
    worker.port.on("url", function(url) {
      var videoUrl = validateUrl(url);
      });
    }
  });

When a certain URL is hit, I want to grab an attribute value and send it back to my main.js and work with it. As it works now, I get a message is null error. I've read the documentation but just can't seem to understand how to pass messages.


Edit: Changing onAttach to:

onAttach: function(worker) {
    worker.port.on("url", function(url) {
      var videoUrl = validateUrl(url);
      });
    }
  });

Didn't seem to change much. All I need to do is pass one string from the content script back to my main.js file. However, with the code above, it's telling me that url is null. All the documentation I've looked through seems to indicate that this is how message passing works in Firefox addons.


Edit2: After adding some log statements I noticed a couple things:

1) My content script is being run 10+ times when a URL is matched. I don't know why. The script was being attached to each iFrame.

2) Most of the time the URL comes back null/undefined. However, it works correctly once -- the URL is pulled from the content script and then passed correctly back to the main.js file. It's promptly wiped out by the content script running again, however.

2

2 Answers

2
votes

First make sure that getVideoUrl() is returning a string, I'm guessing

$('meta[itemprop=contentURL]').prop('content')

does not return a string in the cases where you are getting message is null.

Also you had:

onAttach: function(worker) {
  worker.port.on("url", function(message) {
    var videoUrl = validateUrl(message.url);
    videoUrl5k = make5kUrl(videoUrl);
  });
}

Which I changed to:

onAttach: function(worker) {
  worker.port.on("url", function(url) {
    var videoUrl = validateUrl(url);
    videoUrl5k = make5kUrl(videoUrl);
  });
}

Perhaps that resolves the issue? since I do not see the definition for make5kUrl

0
votes

In the pageMod constructor, using the attachTo: 'top' option will attach the script to only the top level document. The content script was being attached to other iFrames and then attempting to run.