Search code examples
firefoxfirefox-addonfirefox-addon-sdk

How to remove an event listener?


I use the Mozilla's Add-on Builder. I am looking for a way to remove an event listener in a contentScript. I use the port way to communicate between add-on script code and the content script code.

The problem is the callback on event "response" is called more than once. I want it to be called once and declared in the callback of the event show.

Can someone help me with that?

main.js code:

var Panel = require("panel").Panel;
var popup_panel = Panel({
    width: 286,
    height: 340,
    contentURL: require("self").data.url("popup.html"),
    allow: { script: true },
    contentScriptWhen: "end",
    contentScriptFile : [
        require("self").data.url("test.js")
    ],
    onShow: function(){
        this.port.emit("show");
        var pan = this;
        this.port.on("hide", function(){pan.hide();});
    }
});

var Widget = require("widget").Widget;
var widget = Widget({
    id: "mozilla-icon",
    label: "My Mozilla Widget",
    contentURL: "http://www.mozilla.org/favicon.ico",
    panel: popup_panel
});

popup_panel.port.on("get", function(){
    popup_panel.port.emit("response");
});

Content script (test.js):

self.port.on("show", function(){
    console.log("show");
    function response(){
        console.log("reponse called");
    }

    self.port.emit("get");
    self.port.once("response", response);
    self.port.removeListener("response", response);
});

full source code


Solution

  • Finally I found the problem. It is a bug in the add-on kit. In the file api-utils/lib/content/content-worker.js in the function removeListener the index is always -1.

    The parameter given in the indexOf is the name of the event and it search a function. It is incorrect.

    So to solve the problem I replace the line let index = listeners[name].indexOf(name); by let index = listeners[name].indexOf(callback);.

    EDIT

    The bug has been fixed. It will publish in the version 1.10 see here