如何在Firefox插件中覆盖内置的XPCOM组件?

4
我第一次尝试开发Firefox扩展程序,涉及编程方面的内容。到目前为止,进展还算顺利,但我遇到了一个问题;我需要覆盖内置的nsIPromptService,并用自己的替代它。
我按照这里的基本XPCOM组件创建教程进行了操作,并成功运行了hello world示例。

https://developer.mozilla.org/en/creating_xpcom_components

一切看起来都很正常,但是我在查找或研究中没有发现如何从javascript中覆盖接口的方法。我看过C++和Java中似乎能够覆盖内置组件的内容,但我找不到任何关于如何从javascript中实现这一点的信息,仅仅尝试改变合同ID也没有奏效;当我尝试从合同ID获取服务(如下),它只会返回原始的、内置组件版本。

var myComponent = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
                                               .getService(Components.interfaces.nsIPromptService);

我是否忽略了一些非常明显的事情?这样覆盖组件的方法是否不正确(我似乎无法在任何地方找到相关信息,所以我不确定我应该做什么...)。


1
我自己没有做过这个,但我认为诀窍在于传递服务的合同ID,然后将相同的接口传递给getService()。除此之外,我认为您最好查看现有的插件,看看它们是否能够实现您想要做的事情。我相信HttpFox使用了这种方法,只是举一个例子。 - Tyler
谢谢您的建议!问题是我需要钩住所有提示/警报等,而不仅仅是我自己调用的那些,这意味着每个人基本上都必须调用我的服务地址(这是不可能的)。我会看一下 HttpFox 看看它们是如何做到的。 - DivineWolfwood
2个回答

3

Neil,谢谢你的建议。那就是我认为我正在做的事情(我确实在做),但如果你实际上是覆盖合同(而不是定义新合同),看起来答案是你必须转到nsIComponentRegistrar并实际注册您的工厂(而不是依靠chrome.manifest来处理它)。这个的一个例子是:

Components.manager.nsIComponentRegistrar.registerFactory(CLASS_ID, CLASS_NAME, CONTRACT_ID, MyPromptServiceFactory);

常量的位置:

const CLASS_ID = Components.ID("{a2112d6a-0e28-421f-b46a-25c0b308cbd0}");

// description
const CLASS_NAME = "My Prompt Service";

// textual unique identifier
const CONTRACT_ID = "@mozilla.org/embedcomp/prompt-service;1";

CLASS_ID/CONTRACT_ID是现有服务的ID。


你能否请发布一下完整的代码,说明如何完成这个任务?我已经努力尝试很长时间了。 - Noitidart

0

您需要使用要覆盖的服务的契约 ID 注册组件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接