Отображение выполняется с помощью nsIChromeRegistry
component, оно обрабатывает все файлы манифеста и создает правила, по которым устраняются URL-адреса chrome://
. Эти правила не раскрываются, потому что они сложнее, чем вы ожидаете. Например. a content
instruction сообщает реестру chrome, как разрешить любой URL, начинающийся с chrome://foo/content/
- реестр знает только префикс, но не отдельные файлы. Обработка locales и skins аналогична, но имеет сложность - может быть более одного языка/скина и того, как разрешен URL-адрес, зависит от текущей локали/оболочки браузера. Наконец, возможно override individual URLs и, например, перенаправить их на другие URL-адреса chrome://
.
Так что все у вас есть nsIChromeRegistry.convertChromeURL(), что разрешит chrome://
URL и дать вам другой URL (file://
, jar:
или даже другой chrome://
URL).
Теперь, если у вас был доступ к private свойства nsChromeRegistryChrome
class, например. путем исправления этого класса - тогда все будет по-другому. Интересующая вас переменная - 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;
}
Редактировать: На Firefox 28, теперь есть лучший путь. Bug 890545 представил (еще не задокументированный) метод nsIComponentManager.getManifestLocations()
, он возвращает экземпляр nsIArray, содержащий список URI каждого активного chrome manifest file. Так что-то подобное, что будет работать, чтобы получить текст всех файлов манифеста:
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);
}
}
Тем не менее, анализ манифестов является то, что вы должны сделать сами в этом сценарии, в частности manifest, content и override линии - все не совсем простая задача, особенно если вы правильно считаете флаги.
Спасибо. Я просмотрел nsChromeRegistry. Я думаю, что Mozilla использует комбинацию Hashtables и Arrays для управления сопоставлениями. Я пытался сказать, могу ли я получить список всех таких сопоставлений из этих структур данных (запрос структур данных во время выполнения, скажем, после того, как были отображены все хромы). Это сделал надстройка с именем ChromeList. К сожалению, он не работает в новом Firefox. – Anton
@Anton: Это расширение анализирует манифесты «вручную», оно также не может получить доступ к внутренним структурам хромового реестра. –
Я, я знаю. Тем не менее, я пытаюсь ввести код отладки (а не патч) в исходный код Firefox. Вот почему мне нужно понять эти внутренние структуры данных. – Anton