插件SDK -上下文菜单和页面mod工作器

Addon SDK - context-menu and page-mod workers

本文关键字:mod 工作 SDK 上下文 菜单 插件      更新时间:2023-09-26

我一直在研究一个与页面mod通信的上下文菜单,并遇到一个问题。

只要我不刷新页面,我就可以用右键单击到视图中的页面/选项卡发送通信。当我刷新页面时,一个新的工作线程被创建,并且上下文菜单无法与该工作线程通信。

我现在有两个相同的工人,但就像旧的已经过期了。这意味着onMessage:中的这个循环不工作,因为它拾取了第一个worker。

for (index = 0; index < workers.length; index += 1) {
    if (workers[index].tab.index === tabs.activeTab.index) {
    workers[index].port.emit("rightClick", string, ss.storage.product);
    }
}

我一直在寻找在刷新时删除旧工,但似乎没有选择这样做。我是否从根本上忽略了对工人的处理?

我收到的错误是:错误:该页面当前被隐藏,不能再使用,直到它再次可见。

这与这样一个事实是一致的,即就工人而言,我现在正在同一选项卡中查看一个新页面。我想工人。On ('detach', function(){})应该处理这个,但似乎这只是在标签的关闭。

如有任何建议,不胜感激。

添加好了,稍作休息后,我决定使用其他地方推荐的detachWorker函数进行分离。我把它放在pageMod对象的顶部,如下所示

// Clean up duplicate worker
for (index in workers) {
    if(workers[index].url === worker.url && workers[index].tab.index === worker.tab.index) {
        detachWorker(workers[index], workers);
    }
}

这解决了这个问题(目前),虽然我不认为这是正确的方法。

我也碰到了这个。Worker对象似乎保留了一些过去的页面(并且在历史中返回和前进时重用)。解决方案是监听pagehidepageshow事件,以便仅在数组中保留当前显示的工人:

var pageMod = require("sdk/page-mod");
var array = require('sdk/util/array');
var pageWorkers = [];
pageMod.PageMod({
  onAttach: function(worker) {
      array.add(pageWorkers, worker);
      worker.on('pageshow', function() { array.add(pageWorkers, this); });
      worker.on('pagehide', function() { array.remove(pageWorkers, this); });
      worker.on('detach', function() { array.remove(pageWorkers, this); });
      // do other work.
  }
});

注意array.add函数负责不添加重复项

我不太明白你的意思。您提到的事件detach也会在重新加载选项卡时触发:

const { add, remove } = require("sdk/util/array");
const workers = [];
require("sdk/page-mod").PageMod({
  include: "*",
  contentScript: "alert('executed')",
  onAttach: function(worker) {
    add(workers, worker);
    console.log('attached: ', workers.length);
    worker.on('detach', function() {
      remove(workers, worker);
      console.log('detached: ', workers.length);
    })
  }
});

当我重新加载页面时,分离的侦听器被执行。无论如何,要检查与工作关联的选项卡是否为活动的选项卡,您应该能够比较选项卡对象:(workers[index].tab === tabs.activeTab)。还要注意,在Add-on SDK 1.14中,选项卡也有id属性,因此您可以使用它来标识它们自己。不推荐索引的for…in循环:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...in查看描述部分。我宁愿用for…

for (let worker of workers) { ... }

ZERO是正确的,事件detach在重新加载时触发。
但是,当我在同一选项卡中打开不同的页面时,没有发出分离事件!
所以,也就是说,当我在标签1中加载了一些页面A,并单击在同一标签1中打开不同页面B的链接时,我必须手动分离页面A的worker (?)

var workers = [];    
require('page-mod').PageMod({
  include: '*',
  contentScriptWhen: 'end',
  contentScript: [require('self').data.url('bla.js')],
  onAttach: function(worker) {
    var w = workers.length;
    while (w--) {
      if (worker.tab === workers[w].tab) {
        workers.splice(w, 1);
        break;
      }
    }
    workers.push(worker);
    // other stuff
  }
});