Search code examples
javascriptdomfirefox-addonpagemethods

Make Pagemod and Page-worker modules to work together?


I'm working on a Firefox extension project that requires me to use the TAB key to toggle through all the links on the page, extract the its URL, fetch its source code, and parse it.

Currently, I'm able to use TAB key to toggle through the page to get its URL by the following:

exports.main = function() {};
var pageMod = require("page-mod");

pageMod.PageMod({
  include: "*.org",
  contentScriptWhen: 'ready',
  contentScript:

  'document.onkeydown = function(ev) {var key; ev = ev || event; key = ev.keyCode; if (key == 9) { setTimeout (function(){console.log(document.activeElement.href);'+
  '}, 1000 ); } };'+

  'var a = "Access Tab URL Extraction: New Page Found."; console.log(a);'
});

... and get fetch the source code of any give URL with the following (Wikipedia for example):

exports.main = function() {};

console.log("Start");
var pageWorkers = require("page-worker");

var script = "var elements = document.body.innerHTML; " +

             "  postMessage(elements) " ;

// Create a page worker that loads Wikipedia:
pageWorkers.Page({
  contentURL: "http://en.wikipedia.org/wiki/Internet",
  contentScript: script,
  contentScriptWhen: "ready",
  onMessage: function(message) {
    console.log(message);
  }
});

So, how can I pass in the URL I got from the Pagemod (in this case document.activeElement.href) into Page-worker's contentURL and make it fetch and display the source code everytime I press the TAB key as new URLs keep being extracted in Pagemod.

I tried the following but it does not work, seems one cannot call page-worker as part of the page-mod's contentScript?

exports.main = function() {};
var pageMod = require("page-mod");
var pageWorkers = require("page-worker");


pageMod.PageMod({
  include: "*.org",
  contentScriptWhen: 'ready',
  contentScript:

//Get New URLs by Pressing the Tab Key

'document.onkeydown = function(ev) { var key; ev = ev || event; key = ev.keyCode; if (key == 9) { setTimeout (function(){console.log(document.activeElement.href);'+

  '}, 1000 ); } };'+



//Fetch new URL source code

'document.onkeyup = function(ev) { var key; ev = ev || event; key = ev.keyCode; if (key == 9) {'+

'pageWorkers.Page({'+
'contentURL: "document.activeElement.href",'+
'contentScript: "var elements = document.body.innerHTML;"+"postMessage(elements)",'+
'contentScriptWhen: "ready",'+
'onMessage: function(message) {'+
'console.log(message);'+
'}'+
'});'+

   ' } };'

});

Any help will be greatly appreciated! :)


Solution

  • Content scripts can't use addon-sdk resources, as they run in the context of the webpage. So you have to use message passing. Your keypress handler should pass a message back to the addon with something like

      self.port.emit('url', document.activeElement.href)
    

    and then in your page-mod declaration you'd receive the message and create a page-worker to get the source:

    onAttach: function(worker) {
      worker.port.on('url', function(url) {
        pageWorkers.Page({
          contentURL: url,
          contentScript: script,
          contentScriptWhen: "ready",
          onMessage: function(message) {
            console.log(message);
          }
        });
      });
    }
    

    Note that you'd probably want some validation so you only pass URLs back to the addon, and you'd probably want to deal with errors loading the page in the page-worker.