我正在尝试加载此tutorial后的框架脚本:
mm.loadFrameScript("chrome://myextension/content/content.js", true);
我的扩展程序是附加SDK类型。该教程说我需要先在content
中指定chrome.manifest
。我甚至没有该文件(仅package.json
和index.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页面上找到问题的线索。
答案 0 :(得分:2)
该教程通常针对XUL或restartless/bootstrap加载项。该层次结构中更合适的教程是:Multiprocess Firefox and the SDK。该页面的要点是,如果您使用附加SDK API,您的扩展应该只适用于多进程Firefox,如果它不是,那么它就是bug in the Add-on SDK。
通常,附加SDK扩展程序将使用其中一个High Level APIs来加载content scripts。将使用的主要API是tabs和page-mod,但还有其他API(例如context-menu和page-worker)。还有Low-Level APIs remote/parent和remote/child来处理processes和frames。
但是,如果您愿意,可以使用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来加载您用来访问可能在另一个进程中的内容的脚本。
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);
content
行:
chrome.manifest 文件的content
行是:
content packagename uri/to/files/ [flags]
这是由空格分隔的至少3个字段,其中包含flags的一个或多个可选附加字段。
第一个字段为content
,表示这是一行定义chrome://packagename/content
网址的解析方式。
第二个字段是packagename
。这是您组成的名称,不得与Firefox已使用的其他软件包名称或其他扩展名添加的名称冲突。 通常,这将是您用于加载项的name
,或name
或id
的一些排列,如果使用多个{{ 1}}行。附加SDK的名称和ID通常是name
文件中包含的id
和package.json属性的值,但可能是somewhat different。 content
不一定是您的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/parent和remote/child模块。您可以使用remote_require
加载流程脚本,然后在流程脚本中使用remote / child来枚举帧脚本全局对象的sdk包装。