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

发布于 2024-10-30 00:33:40 字数 761 浏览 5 评论 0原文

我第一次涉足 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);

这里有什么明显的东西是我遗漏的吗?这是覆盖组件的错​​误方法吗(我似乎在任何地方都找不到任何东西,所以我不太确定我应该做什么..)。

I'm taking a foray into Firefox extension development for the first time, and so far it's been pretty comfortable going, but I'm running into a problem; one of the things I need to do overwriting the built-in nsIPromptService and replacing it with something of my own instead.

I walked through the basic XPCOM component creation tutorial here and got the hello world one working:

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

And everything in that seems to work fine, but nothing I've been able to find or research shows how I can overwrite an interface from javascript. I've seen things in C++ and Java that seem to be able to overwrite the built-in components, but I can't find anything about doing this from javascript, and just trying to change the contract ID didn't work; when I try to get the service from the contract ID (as below), it just returns the original, built-in component version.

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

Is there something really obvious here that I'm missing? Is this the wrong way to go about overriding components (I can't seem to find anything anywhere, so I'm not really sure what I should be doing..).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别理我 2024-11-06 00:33:40

尼尔,谢谢你的建议。这就是我认为我正在做的事情(而且我确实这样做了),但是如果您实际上要覆盖合同(而不是定义新合同),那么答案似乎是您必须转到 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。

Neil, thanks for the suggestion. That's what I thought I was doing (and I was), but if you're actually overriding a contract (instead of defining a new one), it looks like the answer is that you have to go to the nsIComponentRegistrar and actually register your factory (rather than relying on the chrome.manifest to handle it for you). An example of this would be:

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

Where the constans were:

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";

Where the CLASS_ID/CONTRACT_ID were the IDs for the pre-existing service.

为你鎻心 2024-11-06 00:33:40

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

You need to register your component using the contract id of the service that you want to override.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文