在Firefox附加组件SDK扩展中使用chrome:// myAddon / content / URL

时间:2016-06-18 12:06:32

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

我正在尝试加载此tutorial后的框架脚本:

mm.loadFrameScript("chrome://myextension/content/content.js", true);

我的扩展程序是附加SDK类型。该教程说我需要先在content中指定chrome.manifest。我甚至没有该文件(仅package.jsonindex.js)。所以我用一行创建了myextension/chrome.manifest

content content.js

并创建了一个文件myextension/content/content.js

console.log("content script executed");

问题是,在mm.loadFrameScript("chrome://myextension/content/content.js", true);执行index.js时,我收到错误:

No chrome package registered for chrome://myextension/content/content.js

我想是因为清单文件错误或者没有全部注册?但是我无法在chrome registration页面上找到问题的线索。

2 个答案:

答案 0 :(得分:2)

该教程通常针对XULrestartless/bootstrap加载项。该层次结构中更合适的教程是:Multiprocess Firefox and the SDK。该页面的要点是,如果您使用附加SDK API,您的扩展应该只适用于多进程Firefox,如果它不是,那么它就是bug in the Add-on SDK

通常,附加SDK扩展程序将使用其中一个High Level APIs来加载content scripts。将使用的主要API是tabspage-mod,但还有其他API(例如context-menupage-worker)。还有Low-Level APIs remote/parentremote/child来处理processesframes

但是,如果您愿意,可以使用frame scripts。附加SDK扩展实际上是无重新启动/引导扩展,由附加SDK包装。因此,如果确实希望这样做,您可以在Add-on SDK扩展中的引导扩展中完成大部分操作。但是,最好保留Add-on SDK提供的API。如果您使用这些API,那么您将失去Add-on SDK为您提供的一些优势(例如,将实际的实现隐藏在不打算更改的API之后)。

存在帧脚本和内容脚本以执行相同的功能:访问已经加载到可能受不同进程控制的区域的内容(例如,HTML页面)(e10s)。很大程度上,两个不同名称所指的东西非常相似。但是,您几乎只会看到术语"框架脚本"仅用于XUL和引导程序扩展,而内容脚本"几乎总是指的是Add-on SDK脚本。

同样,您可能最好使用Add-on SDK API来加载您用来访问可能在另一个进程中的内容的脚本。

附加SDK:使用data目录:

对于Add-on SDK扩展,不使用chrome:// URL,而是使用 [add-on base directory] ​​/ data / 目录并获取URL更合适使用sdk/self API引用您的文件。你可以这样做:

var self = require("sdk/self");
let frameScriptUrl = self.data.url("content.js")

然后您的loadFrameScript()行将是:

mm.loadFrameScript(frameScriptUrl, true);

使用 chrome.manifest

content行:
chrome.manifest 文件的content行是:

content packagename uri/to/files/ [flags]

这是由空格分隔的至少3个字段,其中包含flags的一个或多个可选附加字段。

第一个字段为content,表示这是一行定义chrome://packagename/content网址的解析方式。

第二个字段是packagename。这是您组成的名称,不得与Firefox已使用的其他软件包名称或其他扩展名添加的名称冲突。 通常,这将是您用于加载项的name,或nameid的一些排列,如果使用多个{{ 1}}行。附加SDK的名称和ID通常是name文件中包含的idpackage.json属性的值,但可能是somewhat differentcontent不一定是您的packagename或ID,它只需要对加载到Firefox中的所有内容都是唯一的。

第三个字段是目录的URL,其中包含您要引用的文件。此URL可以是绝对的,也可以是相对于 chrome.manifest 文件的位置。此网址必须以name结尾。

Firefox会在附加组件的基本目录中查找 chrome.manifest 文件(与 package.json 所在的文件相同)。虽然可以使用manifest关键字添加其他 chrome.manifest 文件,但这不常见。

原型附加组件 chrome.manifest 将包含如下行:

/

使用 chrome.manifest content packagename chrome/content 行有效的Chrome网址时,您会使用content之类的内容。这将引用位于 [add-on base directory] ​​/ chrome / content / 目录中的名为chrome://packagename/content/myScriptFile.js的文件。

另一个例子:
chrome.manifest用于

myScriptFile.js

在这种情况下,content myAddOnName my/special/directory/ 将引用文件 [add-on base directory] ​​/my/special/directory/myScriptFile.js

您的具体问题:
虽然您说您正在关注tutorial,但您实际上并未对chrome.manifest文件的内容这样做。当您更改包含的文件时,您也不会遵循chrome://myAddOnName/content/myScriptFile.js行应包含的description。但是,即使您完全按照本教程进行操作,也不会有一个正常运行的附加组件,因为该教程对于该文件中的内容不正确。教程中的行实际上是无效的。我更正了MDN documentation中的那一行。

chrome.manifest 中的行需要使用的内容取决于您希望用于扩展程序的目录结构。

如果您希望 content.js 存在于目录 [附加基本目录] / chrome / content / 中,并由content引用那么 chrome.manifest chrome://myAddOnName/content/content.js行将是:

content

注意:即使您在content myAddOnName chrome/content/ 的问题(仅限myextension网址)中使用了chrome://,我也没有在此处使用它来尝试更清楚地指出packagename应该是您选择的名称,该名称对您的加载项而言是唯一的。我不清楚您在问题中使用packagename作为您在扩展程序中实际使用的占位符。如果这是您使用的实际文本而不是问题的占位符,那么我会提醒您,包名myextension不是很独特,并且有合理的机会存在于其他随机扩展中。如果是这样,它可能会或可能不会导致其中一个或两个扩展程序出现故障。

答案 1 :(得分:2)

SDK提供了框架脚本和流程脚本的抽象(除了页面模式和标签附加机制,也依赖于框架脚本),remote/parentremote/child模块。您可以使用remote_require加载流程脚本,然后在流程脚本中使用remote / child来枚举帧脚本全局对象的sdk包装。