Firefox addon 更新realtime worker.emit中多个选项卡中的首选项

Firefox addon 更新realtime worker.emit中多个选项卡中的首选项,firefox-addon,firefox-addon-sdk,Firefox Addon,Firefox Addon Sdk,我正在编写一个扩展,它将调用一个内容脚本并执行一些工作。内容脚本的活动取决于首选项。我希望首选项能够实时更新,而不仅仅是在加载选项卡时。我已经在(“,onPrefChange”)上设置了一个监听器require(“sdk/simple prefs”)将正确触发 var tabs = require("sdk/tabs"); var self = require("sdk/self"); var prefSet = require("sdk/simple-prefs"); var pageMod

我正在编写一个扩展,它将调用一个内容脚本并执行一些工作。内容脚本的活动取决于首选项。我希望首选项能够实时更新,而不仅仅是在加载选项卡时。我已经在(“,onPrefChange”)上设置了一个监听器
require(“sdk/simple prefs”)将正确触发

var tabs = require("sdk/tabs");
var self = require("sdk/self");
var prefSet = require("sdk/simple-prefs");
var pageMod = require("sdk/page-mod");
var data    = self.data;

var workers = {};

prefSet.on("", onPrefChange);

function onPrefChange(prefName) {
    for each (var tab in tabs){     
        // the below code created a new worker and re-attached the script instead of reusing the worker
        // created in tabs.on('ready'...
        //changeWorker = tab.attach({
        //  contentScriptFile: self.data.url("my-script.js"),
        //});       
        //changeWorker.port.emit("setPrefs", prefSet.prefs);
        workers[tab.id].port.emit("setPrefs", prefSet.prefs);
    }
    console.log(workers);
}

tabs.on('ready', function(tab) {
    worker = workers[tab.id] = tab.attach({
        contentScriptFile: self.data.url("my-script.js"),
    });     
    worker.port.emit("setPrefs", prefSet.prefs);
});

tabs.on('close', function(tab) {
    delete workers[tab.id];
});
我从中开始编写一些代码,但我没有使用PageMod。我试着用我的代码做一些类似的事情,但它不能从
ready
侦听器正常启动。在我的
onPrefChange
函数中,我最初是重新附加
contentScriptFile
,但这创建了一个新的附件和工作程序。从中,我发现我可以创建一个worker数组,然后稍后调用它。上面的代码按预期工作,但这似乎效率较低

我想知道是否有办法在
ready
监听器内部设置
onPrefChange
,或者遍历选项卡列表并找到附加的工作人员;我不知道如何迭代选项卡并重用已经创建的worker(这样就不需要管理
workers
数组)。另一种问这个问题的方式是给一个标签,我如何列出所有工人的附件?对首选项的更新应该会影响所有打开的选项卡,而不仅仅是上次创建的worker或当前选项卡,我尝试的其他一些方法就是这样


编辑:

如果在一个选项卡中,我从
http://www.example.com
然后导航到
http://www.example.org
和点击后退按钮,
设置首选项
将不会启动,我将得到一个错误:“页面当前隐藏,在再次可见之前无法再使用。”。看起来我连接worker然后在遍历选项卡时调用iy的方式是不正确的。我希望它在当前可见的页面上运行,但它只希望在最后加载的页面上运行。也许在每次加载页面时,都会创建一个新的辅助对象并替换数组中的现有值,并且辅助对象会附加到页面而不是选项卡

编辑2: 我一直在尝试使用PageMod来实现这一点。
页面可见可能是另一个问题。我仍然想弄清楚如何使用这段原始代码完成同样的事情,以便理解一切是如何协同工作的。

我无法弄清楚如何在一个选项卡中找到所有工作人员,但为了解决我的问题,我能够迭代所有工作人员。当您有一个单独的工作人员时,您可以查找该选项卡。对于发送首选项,您实际上不需要知道选项卡

这是我附加到首选项更改侦听器的函数:

prefSet.on(“”,onPrefChange=function(){
对于每个(tabWorkers中的var thisTabWorker){
console.log(“tab worker tab id=“+thisTabWorker.tab.id”);
log(“tab worker url=“+thisTabWorker.url”);
thisTabWorker.port.emit(“setPrefs”,prefSet.prefs);
}
});
我创建workers并将内容脚本附加到main.js的下方:

var-tabWorkers=[];
exports.main=函数(){
tabs.on('ready',函数(tab){
tabWorker=tabWorkers[tab.id]=tab.attach({
contentScriptFile:self.data.url(“my script.js”)
});
workerTabId=tabWorker.tab.id;
tabWorker.port.on(“triggerPrefChange”,函数(){
tabWorker.port.emit(“setPrefs”,prefSet.prefs);
});
tabWorker.on('detach',函数(){
删除tabWorkers[workerTabId];
});
}); 
}
triggerPrefChange
是一条消息,可以从加载项脚本发送该消息,以便根据页面事件请求更新更改,基本功能不需要该消息。在这种情况下,如果删除它,只需调用
tabWorker.port.emit(“setPrefs”,prefSet.prefs)本身,因此首选项最初会发送

在我的内容代码中(
my script.js

var someStringPreference='';
self.port.on(“setPrefs”,函数(prefs){
//将首选项数组中的变量指定给
//要在my.script.js中使用的本地变量
someStringPreference=prefs[“someStringPreference”].trim();
});
setPrefs
中,您可能还希望调用一个函数或触发一个事件,以便在有了这些新的首选项后执行某些操作

同样在
myscript.js
中:

window.onpageshow=function(){
self.port.emit(“triggerPrefChange”,”;
};
在附加工作程序时,我不只是发出首选项,而是等到网页触发了
onpageshow
。这也允许我在后退/前进导航时再次发送当前首选项-并非所有情况下都需要这样做

到目前为止,这段代码似乎在做我想做的事情,没有任何错误:只要更改了首选项,就会重新加载
my script.js
中实现的功能,并使用用户设置的新首选项运行