将 WebExtension 从 Chrome 移植到 Firefox?

Ste*_*vie 2 javascript firefox google-chrome google-chrome-extension firefox-addon-webextensions

我制作了一个可运行的 Chrome 扩展,该扩展未打包,只是我计算机上的一个目录。我发现我应该能够很容易地将其移植到 Firefox

我按照 MDN 上的“移植 Google Chrome 扩展”指南进行操作,发现我的清单文件非常完美。

然后,我按照有关如何执行扩展的“在 Firefox 中临时安装”的说明进行操作。

但是,当我单击目录中的任何文件时,什么也没有发生。扩展程序未加载。有什么建议吗?我知道该扩展程序在 Chrome 中运行良好并且加载没有错误。

清单.json

{
  "manifest_version": 2,
  "name": "ER",
  "description": "P",
  "version": "1.0",

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },

  "background": {
    "scripts": [ "background.js" ]
  },

  "content_scripts": [
    {
      "matches": [ "SiteIwant" ],
      "js": [ "ChromeFormFill.js" ],
      "run_at":  "document_idle" 

    }
  ],

  "permissions": [
    "*://*/*",
    "cookies",
    "activeTab",
    "tabs",
    "https://ajax.googleapis.com/"
  ],
  "externally_connectable": {
    "matches": ["SiteIwant"]
  }
}
Run Code Online (Sandbox Code Playgroud)

ChromeFormFill.js

// JavaScript source c
console.log("inside content");
console.log(chrome.runtime.id);
document.getElementById("ID").value = chrome.runtime.id.toString();
Run Code Online (Sandbox Code Playgroud)

背景.js

chrome.runtime.onMessage.addListener(
  function (request, sender, sendResponse) {
      if (request.data === "info") {
          console.log("Recieving Info");
          return true;
      }
 });

chrome.tabs.create(
{
    url: 'myUrl' 
    active: true
}, function (tab) {
    chrome.tabs.executeScript(tab.id, { file: 'Run.js', runAt: "document_idle" });
});
Run Code Online (Sandbox Code Playgroud)

Run.js只会alert('hi').

当我尝试在 Firefox 上加载它时,它不会执行任何操作;什么都不会发生。

Mak*_*yen 5

问题:

manifest.json中:

externally_connectable不支持:1

火狐浏览器不支持externally_connectable. 您可以关注bug 1319168了解更多信息。目前,尚无预计实施时间。

您需要使用不同的方法在站点上的代码和 WebExtension 之间进行通信。这样做的方法是注入内容脚本并在站点代码和内容脚本之间进行通信。执行此操作的常见方法是CustomEvent()window.postMessage()。我的偏好是CustomEvent().

使用window.postMessage()就像在外面大喊你的消息并希望没有其他人在听,或者他们知道他们应该忽略该消息。其他人也在使用的代码window.postMessage()必须已编写为忽略您的消息。您必须编写代码以忽略来自其他代码的任何潜在消息。如果其中任何一个没有完成,那么您的代码或其他代码可能会出现故障。

使用CustomEvent()就像直接与房间里的某人交谈。其他人可能正在倾听,但他们需要知道房间的存在才能这样做,并专门选择倾听您的谈话。自定义事件仅由侦听您指定的事件类型的代码接收,该事件类型可以是您选择的任何有效标识符。这使得错误发生干扰的可能性大大降低。您还可以选择使用多种不同的事件类型来表示不同的事物,或者仅使用一种事件类型并为您的消息定义一种格式,以便区分您需要的任何可能的消息类型。

matches值需要有效(假设是故意编辑的):

您有两行(一行带有尾随,,另一行没有;两者语法正确):

"matches": ["SiteIwant"]
Run Code Online (Sandbox Code Playgroud)

"SiteIwant"需要是有效的匹配模式。我假设这已从有效的内容更改为混淆您正在使用的网站。我用了:

"matches": [ "*://*.mozilla.org/*" ]
Run Code Online (Sandbox Code Playgroud)

在Background.js中:

线路:

    url: 'myUrl' 
    active: true
Run Code Online (Sandbox Code Playgroud)

需要:

    url: 'myUrl',
    active: true
Run Code Online (Sandbox Code Playgroud)

[注意,后面的内容'myUrl'。] 另外,myUrl 需要是有效的 URL。我用了:

    url: 'http://www.mozilla.org/',
Run Code Online (Sandbox Code Playgroud)

Firefox 48 的一个错误(现已修复):

您的线路:

chrome.tabs.executeScript(tab.id, { file: 'Run.js', runAt: "document_idle" });
Run Code Online (Sandbox Code Playgroud)

在 Firefox 48 中,该行在选项卡可用之前执行。这是一个错误。它已在Firefox Developer EditionNightly中修复。您将需要其中之一来测试/继续开发。

ChromeFormFill.js中的问题:

另一个 Firefox 48 错误(现已修复):

chrome.runtime.id is undefined。此问题已在 Developer Edition 和 Nightly 中修复。

潜在的内容脚本问题:

我假设您的 HTML 有一个 ID = 的元素'ID'。如果没有,你的document.getElementById("ID")将会是null。您不检查返回值是否有效。

运行您的示例代码

一旦所有这些错误都得到解决,并在 Firefox Nightly 或 Developer Edition 下运行,它就可以正常工作。但是,您没有任何依赖于 is 的东西externally_connectable,这将无法发挥作用。


  1. 阿加吉注意到我忘记将这个问题包含在我的答案的原始版本中。