Отображение выполняется компонентом nsIChromeRegistry
, он обрабатывает все файлы манифеста и создает правила, по которым chrome://
URL-адреса разрешаются.Эти правила не раскрыты уже потому, что они сложнее, чем вы, очевидно, ожидаете.Например, инструкция content
сообщает реестру chrome, как разрешать любые URL-адреса, начинающиеся с chrome://foo/content/
- реестру известен только префикс, но не отдельные файлы.Обработка locales и skins аналогична, но имеет сложность - может быть несколько локалей / скинов, и то, как разрешается URL, зависит от текущей локали / скина браузера.Наконец, можно переопределить отдельные URL и, например, перенаправить их на другие chrome://
URL.
Таким образом, все, что у вас есть, это nsIChromeRegistry.convertChromeURL () , которыйразрешит URL-адрес chrome://
и предоставит вам другой URL (file://
, jar:
или даже другой chrome://
URL).
Теперь, если у вас был доступ к частным свойствамиз nsChromeRegistryChrome
класса , например, путем исправления этого класса - тогда все будет иначе.Интересующая вас переменная-член mPackagesHash
.Ключами хеша являются имена пакетов, значения имеют тип PackageEntry
.Также есть mOverrideHash
, содержащий переопределения.Нечто подобное должно работать (код, конечно, не проверен):
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 : Начиная с Firefox 28, теперь есть лучший способ. В ошибке 890545 введен (еще не документированный) метод nsIComponentManager.getManifestLocations()
, он возвращает nsIArray экземпляр со списком URI каждого активного файла манифеста хрома .Таким образом, что-то вроде этого будет работать для получения текста всех файлов манифеста:
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);
}
}
Тем не менее, анализ манифестов - это то, что вам придется делать самостоятельно в этом сценарии, в частности, манифест , content и переопределяют строки - в общем, задача не совсем простая, особенно если вы правильно учитываете флаги.