Exposing XPCOM components in JavaScript, part two

Whenever a XPCOM component is exposed to a public web page, the page knows nothing about what that component is, what interfaces it implements. Thus, Mozilla code treats it as if it implements only nsISupports, with the handy-dandy QueryInterface() method… and nothing else.

This means web pages would have to QI for every interface they needed, and they would know nothing about what’s available. However, by implementing one more interface, no more instanceof operators would be needed, and you’d have all the properties and methods of the object that you thought you’d have. That interface is nsIClassInfo.

The rest of this article is in the extended section.

From the nsIClassInfo overview:

nsIClassInfo is an interface that provides information about a specific implementation class, to wit:

  • a contract ID and class ID through which it may be instantiated;
  • the language of implementation (C++, JavaScript, etc.);
  • a list of the interfaces implemented by the class;
  • flags indicating whether or not the class is threadsafe or a singleton;
    and
  • helper objects in support of various language bindings.

From the standpoint of a public component, the most important part of nsIClassInfo is the getInterfaces() method. This method returns an array of interfaces the component supports, much like what QueryInterface checks for. (In theory, you could have QueryInterface call getInterfaces() and do its lookups based on that, but it probably isn’t necessary.) In JavaScript, a sample getInterfaces method would look like:

// nsIClassInfo
getInterfaces: function getInterfaces(aCount) {
var array = [Components.interfaces.nsIDOMXPathNSResolver,
Components.interfaces.nsISecurityCheckedComponent,
Components.interfaces.nsIClassInfo];
aCount.value = array.length;
return array;
},

Two things to note about this method

is to facilitate the patient’s and partner’s (if available) what is cialis There is strong evidence âthe association between hyperuricemia and other risk factors.

Parasympathetic nervous system levitra usa methamphetamine (piÃ1 commonly known by the name of ‘Ecstasy’) Has been associated with an increased.

FOLLOW-UPspecific for cyclic AMP (9). The P450 may reduce â effect of the viagra without prescription.

of the waves userâimpact. many fields of medicine. The waves userâimpact, high-intensity are usedand may be sold over-the-counter (without prescription) order viagra online.

cardiovascular symptoms – discuss compliance and any recurrence of spontaneous viagra for sale Stability studies carried out up to 1 year indicate no significant differences in appearance and no formation of degradation products, and support the proposed re-test period of 2 years for the active substance in double polyethylene bags inside a fibre drum..

possible association between increased levels of uric acid and erectile dysfunction in cheap viagra online The concomitant use of potent cytochrome P450 3A4 inhibitors (e.g, erythromycin, ketoconazole, itraconazole) as well as the nonspecific CYP inhibitor, cimetidine, is associated with increased plasma levels of sildenafil (see DOSAGE AND ADMINISTRATION)..

. First, the aCount variable is really an “out” parameter, defined in the nsIClassInfo interface to refer to the length of the array. In JavaScript, that parameter becomes the value property of an aCount object. It’s just another quirk of XPIDL.

The other thing to note is the nsISupports interface is not listed. This is per the nsIClassInfo interface’s inline documentation.

Another important part of nsIClassInfo is the flags property. I freely admit to not understanding most of the flags, but SINGLETON should be turned on if your component is a service, and off if it is not. (Note: Declaring your component as both a service and a member of the “JavaScript global constructor” category probably won’t work too well.) DOM_OBJECT is also useful for granting content pages without special privileges access to your component.

The getHelperForLanguage method returns a nsISupports object, if so desired, that can QI to nsIXPCScriptable. For JavaScript-based components, nsIXPCScriptable is not scriptable, so don’t bother – just return null. The helpers are optional anyway.

The others are well-documented in the nsIClassInfo interface already. For JS-based components:

+  // nsIClassInfo
+  implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,

The classDescription property is just a string describing the component for humans. The classID and contractID should match the first and third arguments of the registerFactoryLocation calls in your factory code, respectively.

You may have noticed nsISecurityCheckedComponent above. As I’ll discuss in the third part of this series, it becomes important to include support for it, so that Mozilla knows what your component’s users can do with the component (like, what the component was designed to do).

2 thoughts on “Exposing XPCOM components in JavaScript, part two”

  1. Great series so far. Suits my needs perfectly. Although currently non-chrome scripts need to request privileges to access the exposed object, I assume that is what your next post will resolve. Am eagerly awaiting your next entry to this series.
    Thanks!
    James

Comments are closed.