Javascript 访问附加SDK';主要';来自XUL
在我的加载项中,我使用XUL显示对话框窗口,因为我可以自定义它们的外观以适应加载项的一般样式(如自定义标题栏) 使用,我可以很容易地做到这一点。问题是,我想从XUL对话框调用插件的Javascript 访问附加SDK';主要';来自XUL,javascript,firefox,firefox-addon,firefox-addon-sdk,Javascript,Firefox,Firefox Addon,Firefox Addon Sdk,在我的加载项中,我使用XUL显示对话框窗口,因为我可以自定义它们的外观以适应加载项的一般样式(如自定义标题栏) 使用,我可以很容易地做到这一点。问题是,我想从XUL对话框调用插件的main模块中的某些函数 经过一点搜索,我找到了,它似乎能够完全做到我想要的。但是,我在使用它访问main模块时遇到了问题 首先,我尝试了文档中提到的显而易见的方法 xul\u dialog.js: let {Loader} = Components.utils.import('resource://gre/modul
main
模块中的某些函数
经过一点搜索,我找到了,它似乎能够完全做到我想要的。但是,我在使用它访问main
模块时遇到了问题
首先,我尝试了文档中提到的显而易见的方法
xul\u dialog.js:
let {Loader} = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
let loader = Loader.Loader({
paths: {
'toolkit/': 'resource://gre/modules/commonjs/toolkit/',
'': 'resource:///modules/',
'./': 'resource://<my-addon-name>/root/'
}
});
let main = Loader.main(loader, './main');
let {Loader} = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
let loader = Loader.Loader({
paths: {
'toolkit/': 'resource://gre/modules/commonjs/toolkit/',
'': 'resource://gre/modules/commonjs/',
'./': 'resource://<my-addon-id>-at-jetpack/<my-addon-name>/lib/'
}
});
let main = Loader.main(loader, './main');
这次我在loader.js的第279行遇到了一个相当混乱的错误
Components is not available in this context.
Functionality provided by Components may be available in an SDK
module: https://jetpack.mozillalabs.com/sdk/latest/docs/
However, if you still need to import Components, you may use the
`chrome` module's properties for shortcuts to Component properties:
Shortcuts:
Cc = Components.classes
Ci = Components.interfaces
Cu = Components.utils
CC = Components.Constructor
Example:
let { Cc, Ci } = require('chrome');
当我使用Loader.Require(Loader,{id:'./main'})
而不是Loader.main
时,我会遇到同样的错误。在实例化加载程序时,我甚至尝试将组件
作为globals
传递,但运气不佳
我相当肯定我做了很多错事。我不明白为什么会出现错误,即使在loader.js
中花费了相当多的时间。另外,我还认为还有一个更好的选择,那就是不必为main.js
的路径使用附加id;像那样硬编码似乎不对
非常感谢您的帮助。您需要做的是查找加载程序的特定实例,而不是创建新实例
在main.js
const{id,name,prefixURI}=require(“@loader/options”);
//将这些传递给XUL对话框
在xul.js(或xul对话框脚本的名称)
假设main.js上有一个foo
函数,您可以像这样调用它
mainjssandbox.foo();
当然,不要期望事情像XUL和Add-on SDK实际上混合在一起一样工作 如果您的XUL对话框应该与您的加载项进行交互,那么请不要使用
加载程序
内容,尤其不要使用XPIProvider.bootstrapScopes
@paa建议的。虽然这可能会起作用(目前),但应该注意的是,它依赖于大量的实现细节,这些细节在任何时候都可能发生变化,这使得该解决方案极为脆弱
相反,还有几个其他选项(不是详尽的列表):
- 如果SDK部件打开窗口,您可以使用
,它支持向创建的窗口传递参数,这些参数甚至可以是对象和函数。此外,您还可以拥有窗口调度(自定义)事件,您的SDK部件可以通过调用.openDialog
窗口上的
来侦听这些事件addEventListener
- 如果窗口是从其他地方创建的(例如,由于
,因此从em:optionsURL
),则是另一种通信方式。例如,在AddonManager
上的窗口可以包含对自身的引用。SDK部件只需通过DOMContentLoaded
观察这些通知即可addObserver
- 另一种方法,有点老套,但很有效,就是SDK部分通过监听新窗口,然后通过
将一些API注入例如XPCNativeWrapper.unwrap(subject.QueryInterface(Ci.nsIDOMWindow)).myAddonAPI=something
windowsbrowser.xul
XPIProvider
路由可能是唯一可行的。但是,还是有必要首先联系插件作者,请求添加一些公共API,而不是深入攻击AddonManager和SDK加载程序内部
附言:
如果愿意,可以考虑通过openDialog
将require
或全局范围传递到窗口。通过将其放入您的main.js
,获取全局范围:
const globalScope = this;
再强调也不为过,我们没有设计这些API来与XUL一起工作,这里是dragons等等@canuckistani@paa我明白,我只需要一种方式让对话框与
main
模块进行通信,该模块将处理其余部分。我想,如果将参数传递给对话框是唯一的方法,那么我最好传递消息接收模块。会更干净。@Rikonator将对require
的引用正确地传递到您的加载项中,但将您的公共函数导出到中。或者只需将任何引用传递给函数
。或者传递全局范围。我认为将对象作为参数传递是最好的方法。但是,我只传递希望对话框能够访问的对象,而不是全局范围。更干净、更安全。
const globalScope = this;