Firefox sdk - 内容脚本无法访问self.port

时间:2013-06-01 00:32:27

标签: javascript firefox firefox-addon firefox-addon-sdk

我正在尝试使用他们的sdk创建一个firefox插件,但我不知道如何使我的js脚本通信。目标是制作一个带有表格的面板,有3个复选框,选中后可以隐藏/显示活动选项卡上的某些元素。

以下是脚本:main.js:

exports.main = function() {};

var data = require("sdk/self").data;

var panel1 = require("sdk/panel").Panel({
    width: 215,
    height: 160,
    contentURL: data.url("panelDestroyer.html"),
    contentScriptFile: [data.url("jquery.js"),data.url("panel.js")]
});

require("sdk/widget").Widget({
    id: "open-form-btn",
    label: "Clear",
    contentURL: data.url("mozico.png"),
    contentScriptFile: data.url("jquery.js"),
    panel: panel1
});

var tabs = require("sdk/tabs");

var tabWorkers = {};
tabs.on("ready", function(tab) {
    attachTabWorker(tab);
});
for each (var tab in tabs) {
    attachTabWorker(tab);
}

function attachTabWorker(tab) {
    // Attach and store
    var tabWorker = tabWorkers[tab.id] = tab.attach({
        contentScriptFile: [data.url("clear.js"),data.url("jquery.js")]
    });
    // Clean up
    tabWorker.on("detach", function() {
        if (getTabWorker(tab) === tabWorker) {
            delete tabWorkers[tab.id];
        }
    });
}

function getTabWorker(tab) {
    return tabWorkers[tab.id];
}

function getActiveTabWorker() {
    return getTabWorker(tabs.activeTab);
}


panel1.port.on("show-tag",function(tag){
    getActiveTabWorker().port.emit("show-tag", tag);
    console.log("worker emited");
});

panel1.port.on("clear-tag",function(tag){
    getActiveTabWorker().port.emit("clear-tag", tag);
    console.log("worker emited");
})

painel.js:

    $("#imgD").click(function() {
    if ($(this).is(":checked")) {
        self.port.emit("clear-tag","img");
        console.log("panel emited");
    } else {
       self.port.emit("show-tag","img");
       console.log("panel emited");
    }
});
$("#aD").click(function() {
    if ($(this).is(":checked")) {
        self.port.emit("clear-tag","a");
        console.log("panel emited");
    } else {
        self.port.emit("show-tag","a");
        console.log("panel emited");
    }
});
$("#iframeD").click(function() {
    if ($(this).is(":checked")) {
       self.port.emit("clear-tag","iframe");
       console.log("panel emited");
    } else {
        self.port.emit("show-tag","iframe");
        console.log("panel emited");
    }
});

clear.js:

    function tagHide (tag, hide) {
    $(tag).each(function() {
        if (hide === false) {
            $(this).css({
                "visibility": "visible"
            });
        } else {
            $(this).css({
                "visibility": "hidden"
            });
        }
    });
}

self.port.on('show-tag', function(tag) {
    tagHide(tag, false);
});
self.port.on('clear-tag', function(tag) {
    tagHide(tag, true);
});

为什么我一直没有在painel.js中定义self.port?

2 个答案:

答案 0 :(得分:5)

我认为问题在于您在加载加载项时尝试附加内容脚本

let worker = require("sdk/tabs").activeTab.attach({
    contentScriptFile: data.url("clear.js")
});

认为 activeTab可能还没有准备就绪,只是加载了你的加载项,这通常是在Firefox启动时。也许DOM还没有完全加载,或者SDK无法正确初始化内容脚本的所有组件。

SDK文档states,在使用与内容相关的属性和方法之前,您应该等到ready事件。我假设附加内容脚本也属于该类别,因此您可能需要将其重新编写为:

let worker = null;
require("sdk/tabs").activeTab.on("ready", function(tab) {
    worker = tab.attach({
        contentScriptFile: data.url("clear.js")
    });
});

但这仍然不足,因为用户可能会切换标签。当您在原始 ready上注册activeTab侦听器时,您将不会侦听新激活的选项卡,并且不会将任何内容脚本附加到该选项卡。你需要:

  • 收听所有标签的ready事件;
  • 确保他们所有附加了您的内容脚本;
  • 根据当前活动标签选择合适的工作人员。

我很快就掀起了应该做的事情。您应该能够在getActiveTabWorker()端口事件中使用panel来定位正确的工作人员。它还没有经过测试,所以试一试!

const tabs = require("sdk/tabs");

let tabWorkers = {};
tabs.on("ready", function(tab) {
    attachTabWorker(tab);
});
for each (let tab in tabs) {
    attachTabWorker(tab);
}

function attachTabWorker(tab) {
    // Attach and store
    let tabWorker = tabWorkers[tab.id] = tab.attach({
        contentScriptFile: data.url("clear.js")
    });
    // Clean up
    tabWorker.on("detach", function() {
        if (getTabWorker(tab) === tabWorker) {
            delete tabWorkers[tab.id];
        }
    });
}

function getTabWorker(tab) {
    return tabWorkers[tab.id];
}

function getActiveTabWorker() {
    return getTabWorker(tabs.activeTab);
}

编辑:我不知道 self.port如何定义,但我发现需要修复的更多错误。也许其中一个是间接干扰self

  • main.js正在倾听hide-tag,而您的小组会发出clear-tag。使用clear-tag
  • 您向工作人员发送了一个对象,而您的工作者只需要一个字符串。只需发出tag而不是{tag:tag}
  • 您没有在标签工作者中包含jQuery。在data.url("jquery.js")
  • 中将contentScriptFile添加到attachTabWorker

答案 1 :(得分:1)

我也遇到了同样的问题,然后在SO上发现了这个问题:self.port is undefined error [on mozilla add-on SDK 1.8]

问题在于HTML代码,你必须在main.js和html中调用脚本。从html中删除它,并直接在main.js中声明它将解决此错误。