是否可以从Chrome注册表获取所有条目的列表及其实际物理映射?例如,我正在寻找这样的列表:
chrome://browser/content/browser.xul [实际物理路径]
铬://browser/content/browser.js
...
...
...
chrome://some_extension/content/overlay.xul jar:file:/// path / to / extension /
是否有一些数据结构将这些条目映射到chrome / src /目录源代码中?
答案 0 :(得分:1)
映射由nsIChromeRegistry
component执行,它处理所有清单文件并创建用于解析chrome://
个URL的规则。这些规则没有公开,因为它们比你想象的要复杂得多。例如。 content
instruction告诉chrome注册表如何解析以chrome://foo/content/
开头的任何URL - 注册表只知道前缀而不知道单个文件。 locales和skins的处理方式类似但有复杂性 - 可能有多个区域设置/皮肤以及URL的解析方式取决于浏览器的当前区域设置/外观。最后,可以override individual URLs并将其重定向到其他chrome://
网址。
所以你拥有nsIChromeRegistry.convertChromeURL()即可解析chrome://
网址,并为您提供不同的网址(file://
,jar:
或其他chrome://
网址)。
现在,如果您可以访问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行 - 总而言之,这些并不是一项简单的任务,特别是如果你正确地考虑了旗帜。