1

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.

Community
  • 1
  • 1
joshft91
  • 1,755
  • 7
  • 38
  • 53

2 Answers2

2

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

erikvold
  • 15,988
  • 11
  • 54
  • 98
  • Hi - thanks for the answer. I did a `typeof $('meta[itemprop=contentURL]').prop('content')` and it is indeed a string. I also put a `console.log` statement inside the content script and I can see that when a matching URL is loaded, the `getVideoUrl()` method is called many times (not sure why...) but it is getting in there. Am I sending/receiving the message correctly? – joshft91 Sep 26 '14 at 18:24
  • please see my updated response, since I don't see how `make5kUrl` is defined I think I am missing too much. – erikvold Sep 26 '14 at 18:28
  • Hmm, thanks for the updated response. Those `validateUrl` and `make5kUrl` methods are just a little string manipulation. The problem is that it seems like I can't get anything back from the content script. Also, I'm noticing that the content script is run 10+ times when hitting a valid URL. Is there something that causes it to run more than once? – joshft91 Sep 26 '14 at 18:34
  • Solution found. Edited at the top - thanks again for the help. – joshft91 Sep 26 '14 at 19:41
0

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.

joshft91
  • 1,755
  • 7
  • 38
  • 53