How to release and listen to the event between pagemod and widget?

I am using addon-sdk. I have a widget, and after clicking on the widget I want to do something with the website (whether changing the page or reading the depth of the DOM).

So my thought after reading https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/page-mod#Communicating_With_Content_Scripts would be the following:

  • pagemod is activated at a matching URL (in this case ANY)
  • Click on the widget that suits the event left-click. Then it emits widget-click.
  • Pagemod receives an event widget-clickand returns an event with a name from-pagemod.
  • from-pagemod does something on a web page.

I see the following output in stdout:

console.log: project: about to emit widget-click
console.log: project: after emitting widget-click

So pagemod did not receive this event or was never configured. I'm not sure what is missing in this simple case. Any help is appreciated.

Here lib/main.js.

var widgets = require('sdk/widget');
var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;
var tabs = require("sdk/tabs");

exports.main = function() {
    var widget = widgets.Widget({
        label: "widget label",
        id: "widget-id",
        contentURL: data.url("off.png"),
        contentScriptFile: [data.url("widget.js"), data.url("page.js")]
    });

    widget.port.on("left-click", function() {
        console.log("about to emit widget-click");
        widget.port.emit("widget-click", "foo");
        console.log("after emitting widget-click");
    });


    var page = pageMod.PageMod({
        include: "*",
        contentScriptWhen: "end",
        contentScriptFile: data.url("page.js"),
        onAttach: function(worker) {
            worker.port.on("widget-click", function(msg) {
                console.log("on widget-click, ready to emit from-pagemod event");
                worker.port.emit("from-pagemod", "foo");
            });
        }
    });
};

Here page.js

self.port.on("from-pagemod", function(msg) {
    console.log("inside from-pagemod listener");
    // read DOM or modify the DOM
});

Here widget.js

this.addEventListener('click', function(event) {
  if(event.button == 0 && event.shiftKey == false)
    self.port.emit('left-click');
}, true);
+3
source share
2 answers

Change 2 to answer the question:

If you want to do something on the page in widgets, clicking when the contents of the script is already connected, register your listener widgetsomewhere, you have access to page-worker. You can do this by putting the code widget.port.oninside pageMod onAttach(), but then it will only work for the very last page attached. The best way to make it functional is to save all workers, and then check if the worker has the current tab when the widget clicks, for example:

main.js

var workers = [];

widget.port.on("left-click", function() {
  console.log("about to emit widget-click");
  var worker = getWorker(tabs.activeTab);
  if (worker) {
    worker.port.emit("widget-click", "foo");
    console.log("after emitting widget-click");
  }
});

var page = pageMod.PageMod({
  include: "*", // TODO: make more specific
  contentScriptWhen: "end",
  contentScriptFile: data.url("page.js"),
  onAttach: function(worker) {
    workers.push(worker);
    worker.on('detach', function() {
      detachWorker(worker);
    });
    // could be written as
    // worker.on('detach', detachWorker.bind(null, worker);
  }
});

function detachWorker(worker) {
  var index = workers.indexOf(worker);
  if(index!==-1) workerArray.splice(index, 1);
}

function getWorker(workers, tab) {
  for (var i = workers.length - 1; i >= 0; i--) {
    if (workers[i].tab===tab) return worker;
  }
}

page.js

self.port.on("widget-click", function(msg) {
  console.log("inside widget-click listener");
  // read DOM or modify the DOM
});

, , , , - , .


: .

script ( script , , )

main.js

var widgets = require('sdk/widget');
var data = require("sdk/self").data;
var tabs = require("sdk/tabs");

exports.main = function() {
    var widget = widgets.Widget({
        label: "widget label",
        id: "widget-id",
        contentURL: data.url("off.png"),
        contentScriptFile: data.url("widget.js")
    });

    widget.port.on("left-click", function() {
        console.log("about to attach script");
        var worker = tabs.activeTab.attach({
            contentScriptFile: data.url("page.js");
        });
        worker.port.on('message from content script', function(someVariable){
            //Now I can do something with someVariable in main.js
        });
    });
};

page.js

// read DOM or modify the DOM
//I'm done, I'll send info back to the main script. This is optional
self.port.emit('message from content script', someVariable);

: , , . , Tutorials - , -, SDK. .

+3

a port - script : widget.js pagemod - page.js. widget.port.emit("widget-click", "foo");, widget.js, self.port.on('widget-click') pagemod. pagemod , main.js, , .

+1

All Articles