简体   繁体   English

从XUL访问附加SDK“ main”

[英]Access Add-On SDK 'main' from XUL

In my add-on, I'm using XUL to display dialog windows because I can customize their appearance to suit the add-on's general style (like a custom titlebar ). 在我的附加组件中,我使用XUL来显示对话框窗口,因为我可以自定义其外观以适合附加组件的常规样式(例如自定义titlebar )。

Using the migration guide , I'm able to do this easily. 使用迁移指南 ,我可以轻松做到这一点。 The thing is, I would like to call certain functions in the add-on's main module from the XUL dialog. 问题是,我想从XUL对话框中调用附加组件main模块中的某些功能。

After a bit of searching I found the loader module , which seems to be able to do exactly what I want. 经过一番搜索,我发现了loader模块 ,它似乎能够完全满足我的要求。 But, I'm experiencing trouble in using it to access the main module. 但是,使用它访问main模块时遇到麻烦。

First, I tried the obvious approach as mentioned in the documentation; 首先,我尝试了文档中提到的显而易见的方法。

xul_dialog.js : xul_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');

I got an error that './main' was not found at resource://<my-addon-name>/root/ . 我在resource://<my-addon-name>/root/找不到'./main'错误。 Figuring that I was using the incorrect paths, I experimented a bit until I could remove all path associated errors. 弄清楚我使用的路径不正确,我做了一些实验,直到可以消除所有与路径相关的错误。

xul_dialog.js : xul_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://gre/modules/commonjs/',
        './': 'resource://<my-addon-id>-at-jetpack/<my-addon-name>/lib/'
    }
});

let main = Loader.main(loader, './main');

This time I got a rather confusing error at loader.js, line 279 . 这次,我在loader.js, line 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');

I get the same error when I use Loader.Require(loader, {id: './main'}) instead of Loader.main . 当我使用Loader.Require(loader, {id: './main'})而不是Loader.main时,出现相同的错误。 I even tried passing Components as globals when instantiating the loader, but without much luck. 我什至尝试在实例化加载程序时将Components作为globals传递,但是运气不佳。

I'm fairly certain that I'm doing a lot of things wrong. 我可以肯定我做错了很多事情。 I don't understand why I'm getting the error, even after spending quite a bit of time in loader.js . 即使在loader.js花了很多时间,我也不明白为什么会出错。 Plus, I also think that there would be a better alternative than having to use the add-on id for the path to main.js ; 另外,我还认为,有一个更好的选择,那就是不必使用附加ID来main.js的路径; hard-coding it like that doesn't seem right. 像这样硬编码似乎不正确。

Any help would be really appreciated. 任何帮助将非常感激。

What you have to do is to find a specific instance of Loader , not create a new one. 您要做的是找到Loader的特定实例,而不是创建一个新实例。

At main.js 在main.js

const { id, name, prefixURI } = require("@loader/options");
//pass these to the XUL dialog

At xul.js (or whatever is the name of the xul dialog script) 在xul.js(或xul对话框脚本的名称)中

Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm");
var extensionscope = XPIProvider.bootstrapScopes[id];
var mainjssandbox = extensionscope.loader.sandboxes[prefixURI + name + "/lib/main.js"];

Assuming there is a foo function at main.js, you can call it like 假设main.js中有一个foo函数,您可以像这样调用它

 mainjssandbox.foo();

Of course don't expect things to work as if XUL and Add-on SDK actually blended into one thing. 当然,不要指望事情像XUL和Add-on SDK实际上融为一体。

If it is your XUL dialog that should interact with your add-on, then please don't use the Loader stuff and in particular do not go the XPIProvider.bootstrapScopes @paa suggested. 如果这是你的 XUL对话框,应与你的附加组件交互,那么请不要使用Loader的东西,尤其是不走XPIProvider.bootstrapScopes @paa建议。 While this might work (for now), it should be noted that it relies on tons of implementation details that are subject to change at any point making this solution extremely fragile. 尽管这可能行得通(暂时),但应注意,它依赖大量的实现细节,这些细节可能随时更改,从而使该解决方案非常脆弱。

Instead there are a couple of other options (not an exhaustive list): 而是有几个其他选项(不是详尽的列表):

  • If the SDK part opens the windows, you may use .openDialog which supports passing arguments to the created window, and these arguments can even be objects and functions. 如果SDK部分打开了窗口,则可以使用.openDialog ,它支持将参数传递给创建的窗口,这些参数甚至可以是对象和函数。 Also, you can have the window dispatch (custom) events, and which your SDK part can listen to by calling addEventListener on the window the .openDialog call returns. 此外,您还可以进行窗口调度(自定义)事件,并且SDK部件可以通过在.openDialog调用返回的window上调用addEventListener来监听。
  • If the window is created from somewhere else (eg from the AddonManager because of em:optionsURL ) then the nsIObserverService is another way to communicate. 如果窗口是从其他地方创建的(例如,由于em:optionsURL AddonManager而从AddonManager创建),则nsIObserverService是另一种通信方式。 The window could eg .notifyObservers on DOMContentLoaded containing a reference to itself. 该窗口可以例如在DOMContentLoaded .notifyObservers包含对自身的引用。 The SDK parts would just have to observe such notifications by addObserver . SDK部分仅需通过addObserver观察此类通知。
  • Another way, a bit hacky but working, is the SDK part listening to new windows via nsIWindowWatcher.registerNotification and then injecting some API into eg browser.xul windows by XPCNativeWrapper.unwrap(subject.QueryInterface(Ci.nsIDOMWindow)).myAddonAPI = something . 另一种方法,有点棘手,但有效的是,SDK部分通过nsIWindowWatcher.registerNotification侦听新窗口,然后通过XPCNativeWrapper.unwrap(subject.QueryInterface(Ci.nsIDOMWindow)).myAddonAPI = something将一些API注入到browser.xul窗口中XPCNativeWrapper.unwrap(subject.QueryInterface(Ci.nsIDOMWindow)).myAddonAPI = something

Be sure to handle unloading or your add-on well - it is still restartless -, ie reverse any changes you've done and remove any observers and so on again. 确保处理好卸载程序或附加组件-它仍然不会重启-即撤消所做的所有更改并再次删除所有观察者,依此类推。

If you want to interact with SDK addons not created by you, then the XPIProvider route might be the only feasible. 如果要与您未创建的SDK插件进行交互,则XPIProvider路由可能是唯一可行的方法。 But still, it might be worth contacting the add-on author first asking for the addition of some public API instead of hacking deep into the AddonManager and SDK loader internals. 但是,仍然值得联系插件作者首先要求添加一些公共API,而不是深入了解AddonManager和SDK加载器内部。

PS: PS:

Considering passing require or the global scope to your window via openDialog if you want to. 如果需要,可以考虑通过openDialogrequire或全局范围传递给窗口。 Get the global scope by placing this into your main.js : 通过将其放入main.js获取全局范围:

const globalScope = this;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 页面加载后从XUL调用Init(Firefox附加组件) - Call Init from XUL after Page Loads (Firefox add-on) 如何在Firefox附加SDK中访问div? - How to access div in Firefox Add-on SDK? 如何使用XUL,SDK或WebExtensions技术从Firefox插件中的JavaScript动态修改CSS规则集(例如,使用类选择器)? - How to dynamically modify CSS rule set (e.g. with a class selector) from JavaScript within Firefox Add-on using XUL, SDK or WebExtensions techniques? 在附加SDK主附加脚本和sdk / page-worker脚本之间进行通信 - Communicate between Add-on SDK main add-on script and sdk/page-worker script 插件SDK:从插件上传WebDAV - Add-on SDK: WebDAV upload from addon Firefox附加SDK:在侧边栏和主脚本之间通信对象 - Firefox Add-on SDK: communicating objects between a sidebar and the main script 如何在运行时使用JavaScript从Mozilla插件中将XUL作为字符串获取? - How can I get the XUL as a string from a Mozilla add-on at run-time using JavaScript? 如何从Firefox的附加SDK(Jetpack)访问places.bookmarks - How to access places.bookmarks from Firefox's Add-on SDK (Jetpack) 如何使用Firefox附加SDK(使用Firefox附加SDK中的服务)设置自定义Cookie - How to set custom cookies using Firefox Add-on SDK (using Services from Firefox Add-on SDK) 如何在另一个附加组件的XUL脚本中覆盖一个方法? - How to override a method in the script of a XUL in another add-on?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM