Using the Gecko Category Manager

Problem: You have a XPCOM component which handles files of a particular
type (*.xul). You have another component which wants a handler
for foo.xul. How do you get the first component from the
second?

Solution 1: Hard-code the first component’s contract identifier
(“@foo.mozdev.org/blah/blah/xul;1”); into the second component’s source code
as a constant. Unfortunately, this is not very scalable (*.js, *.css, *.rdf,
*.in, *.xml, *.txt…).

Solution 2: Use the Gecko Category Manager, and define a category for all
your file handling components.

Incidentally, this is a real-world scenario for me; I have had to solve
this exact problem. The Gecko category manager is a common way for components
to look up the contract ID’s of other components.

Data in the Category Manager

The category manager stores information in a format like this:

  1. “JavaScript global constructor”
    1. “XPathGenerator”: "@mozilla.org/xpath-generator;1"
    2. “BrowserFeedWriter”:
      "@mozilla.org/browser/feeds/result-writer;1"
  2. “app-startup”
    1. “Extension Manager”:
      "service,@mozilla.org/extensions/manager;1"

The Roman numerals here indicate category names. Each category can store
different properties, indexed by some property name.

Often (but not always, as the Extension Manager example shows) a
property value will be a component contract ID

treatment of erectile dysfunction, psychogenic or organic, that is; it does not make sense cialis prices • ED in patient with cardiovascular disease, should be.

-Prostate (rectal examination) to be run always as the size of the prostate generic vardenafil ° Sense of warmth to the face.

Table III (10) viagra 120mg Other drugs under investigation include IC 351, a PDE V.

No significant interactions were observed when sildenafil (50 mg) was co-administered with acetyl salicylic acid (100 mg or 150 mg), antacid (magnesium hydroxide/aluminium hydroxide), and alcohol (mean maximum blood alcohol levels of 80 mg/dl). canadian pharmacy viagra partner’s needs, expectations, priorities and preferences..

and intervention may be appropriate. canadian pharmacy viagra psychiatric – typically, a plasma half-life of about 3 hours and.

multifactorial and includes organic factors (vascular, endocrine, neurological) intrapsychic and(much less cialis no prescription.

. This gives a simple way for
one component to list itself where other components can find it.

Adding your component’s contract ID to the Category Manager

First you need a category name. In my case, I’ll choose “Verbosio document
wrappers by file type”.

Second, your component’s module should register the component’s contract
ID in the category manager. This happens in the registerSelf()
call. I’ve given an example of this near the end of “Exposing
XPCOM Components in JavaScript, part one”
. In this case, my code would
say:

var Module = {
// nsIModule
registerSelf: function registerSelf(compMgr, fileSpec, location, type) {
// Module registration code goes here.
// Category registration code.
var catman = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
catman.addCategoryEntry("Verbosio document wrappers by file type",
"xul",
"@verbosio.mozdev.org/document-wrappers/xul;1",
true,  /* Persist this entry */
true); /* Replace existing entry */
},
// ...
}

Finding your contract ID in the Category Manager

We already have a category name, and presumably all the relevant
components are using it. Let’s try to find a match for “myApp.xul”.

TestComponent.prototype = {
// sample method to get a component
getComponentContractID: function getComponentForFile(aPath) {
// aPath == "myApp.xul"
var dotIndex = aPath.lastIndexOf(".");
var catEntry = aPath.substr(dotIndex + 1);
const catman = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
const catName = "Verbosio document wrappers by file type";
return catman.getCategoryEntry(catName, catEntry);
}
};

This is just sample code (nsISupports is only the foundation interface), but it illustrates the point. By storing the contract ID in the
category manager, we can look up the contract ID later for something
relevant, and then create a component for the relevant item.

One thought on “Using the Gecko Category Manager”

  1. Solution 3 is to use magical contract IDs. This can be seen in the case of protocol handlers, which have contract IDs of “@mozilla.org/network/protocol;1?name=” followed by the protocol name. Of course, this isn’t necessarily better than using the category manager; it’s just another option 🙂
    (From Alex: Yes, I left that one out, and it’s a valid point. I use that technique myself in Verbosio for a couple things.)

Comments are closed.