I'd like to write a XPCOM component that gets exposed as a javascript object in a web page. Something like Google Gears is what I'm seeking. That is, after installing the Google Gears Firefox extension, the javascript object 'google.gears' is available to any web page that wants to use it. I've found lots of mozilla documentation on XPCOM development, but nothing on exposing the component to javascript running in a web page. Is this possible w开发者_开发百科ith XPCOM? Do I need to write a Firefox plug-in instead of an extension?
I'm doing exactly that with a new API in Firefox 4 - nsiDOMGlobalPropertyInitializer - which lets you create a JS object to attach to all windows lazily. This is the way the new Web Console in Firefox 4 is created.
You have to have the following QI property in your component:
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer]),
Here is an example of a full implementation in an extension:
https://github.com/daviddahl/domcrypt/blob/master/extension/domcrypt/components/domcrypt.js
SO basically, QI to Ci.nsIDOMGlobalPropertyInitializer, then make sure your manifest has a line like:
category JavaScript-global-property crypt @droplettr.com/domcrypt;1
see: https://github.com/daviddahl/domcrypt/blob/master/extension/domcrypt/components/domcrypt.manifest
This article seems promising:
Generally speaking, untrusted content (such as a web page) can't do anything with most XPCOM components, including creating them. There are of course exceptions to this policy - DOM objects, for example, are glorified XPCOM components with clearly defined interfaces for public use. For a web page to use a component, however, including calling on any methods or properties, the component has to explicitly tell Mozilla what is allowable and what is not. The nsISecurityCheckedComponent interface defines how that is done.
Source: http://weblogs.mozillazine.org/weirdal/archives/017211.html
The old 3.x way is to register your component in the "JavaScript global property" category. (This still works in 4.x, but you have to use the "JavaScript-global-property" category instead, since category names are no longer allowed to contain spaces.) Your object has to implement the nsIClassInfo interface, plus any interfaces you want to expose to content. It's not terribly useful because you have no way of knowing which content script is accessing your object.
It's doable but you will have to proxy the calls to the XPCOM component. Keep also in mind that it will be probably quite dangerous as well.
See my answer here for how to expose chrome objects to content code.
You can do this with web extensions, I have read and will no longer have support
精彩评论