Is it possible to get a list of all entries from the Chrome registry along with their actual physical mapping? For example, I am looking for a list like this:
chrome://browser/content/browser.xul [actual physical path]
chrome://browser/content/browser.js
...
...
...
chrome://some_extension/content/overlay.xul jar:file:///path/to/extension/
Is there some data structure that maps these entries in the chrome/src/ directory source code?
The mapping is performed by the nsIChromeRegistry
component, it processes all the manifest files and creates rules by which chrome://
URLs are being resolved. These rules aren't exposed, already because they are more complicated than what you apparently expect. E.g. a content
instruction tells the chrome registry how to resolve any URL starting with chrome://foo/content/
- the registry only knows the prefix but not the individual files. Handling of locales and skins is similar but has a complication - there might be more than one locale/skin and how the URL is resolved depends on the current locale/skin of the browser. Finally, it is possible to override individual URLs and for example redirect them to other chrome://
URLs.
So all you have is nsIChromeRegistry.convertChromeURL() that will resolve a chrome://
URL and give you a different URL (file://
, jar:
or even another chrome://
URL).
Now if you had access to private properties of nsChromeRegistryChrome
class, e.g. by patching up that class - then things would be different. The member variable you are interested in is mPackagesHash
. The hash keys are package names, the values have type PackageEntry
. There is also mOverrideHash
containing the overrides. Something like this should work (code is untested of course):
mOverrideTable.EnumerateRead(&PrintOverride, nsnull);
PL_DHashTableEnumerate(&mPackagesHash,
&nsChromeRegistryChrome::PrintPackage,
nsnull);
...
PLDHashOperator
PrintOverride(nsIURI* key,
nsIURI* uri,
void* closure)
{
nsCString keySpec;
nsresult rv = key->GetSpec(&keySpec);
if (NS_SUCCEEDED(rv))
{
nsCString spec;
rv = uri->GetSpec(&spec);
if (NS_SUCCEEDED(rv))
printf("override %s %s\n", keySpec.get(), spec.get());
}
return PL_DHASH_NEXT;
}
PLDHashOperator
nsChromeRegistryChrome::PrintPackage(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *closure)
{
PackageEntry* package = static_cast<PackageEntry*>(entry);
nsCString spec;
nsresult rv = entry->baseURI->GetSpec(&spec);
if (NS_SUCCEEDED(rv))
printf("content %s %s\n", entry->package.get(), spec.get());
nsTArray<nsCString> locales;
entry->locales.EnumerateToArray(&locales);
for (PRUint32 i = locales.Length(); i > 0 ; ) {
i--;
nsCOMPtr<nsIURI> uri = entry->locales.GetBase(locales[i], nsProviderArray::EXACT);
rv = uri->GetSpec(&spec);
if (NS_SUCCEEDED(rv))
printf("locale %s %s %s\n", entry->package.get(), locales[i].get(), spec.get());
}
nsTArray<nsCString> skins;
entry->skins.EnumerateToArray(&skins);
for (PRUint32 i = skins.Length(); i > 0 ; ) {
i--;
nsCOMPtr<nsIURI> uri = entry->skins.GetBase(skins[i], nsProviderArray::EXACT);
rv = uri->GetSpec(&spec);
if (NS_SUCCEEDED(rv))
printf("skin %s %s %s\n", entry->package.get(), skins[i].get(), spec.get());
}
return PL_DHASH_NEXT;
}
Edit: As of Firefox 28, there is now a better way. Bug 890545 introduced the (not yet documented) nsIComponentManager.getManifestLocations()
method, it returns an nsIArray instance listing the URI of each active chrome manifest file. So something like that would work to get the text of all manifest files:
var locations = Components.manager.getManifestLocations();
for (var i = 0; i < locations.length; i++)
{
var uri = locations.queryElementAt(i, Components.interfaces.nsIURI);
var request = new XMLHttpRequest();
request.open("GET", uri.spec, false);
try
{
request.send(null);
parseManifest(uri, request.responseText); // Something for you to implement
}
catch(e)
{
Components.utils.reportError(e);
}
}
Still, parsing the manifests is something you would have to do yourself in that scenario, in particular the manifest, content and override lines - all in all not exactly a simple task, especially if you consider the flags correctly.