4

我正在尝试使用他们的 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");
})

;

痛苦.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");
    }
});

清除.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);
});

为什么我不断得到 self.port 没有在 painel.js 中定义?

4

2 回答 2

5

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

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

认为 activeTab您的插件刚加载时可能还没有准备好,通常是在 Firefox 启动时。可能 DOM 尚未完全加载,或者 SDK 无法正确初始化内容脚本的所有组件。

SDK 文档指出,您应该等到ready事件发生后再使用与内容相关的属性和方法。我假设附加内容脚本也属于该类别,因此您可能需要将其修改为:

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

但这仍然不够,因为用户可能会切换标签。当您在originalready上注册侦听器时,您将不会收听新激活的选项卡,并且不会将任何内容脚本附加到该选项卡。您需要: 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
于 2013-06-01T09:42:10.913 回答
1

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

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

于 2014-10-20T09:25:53.847 回答