获取Firefox chrome注册表中所有条目的列表

时间:2012-02-29 05:01:36

标签: firefox firefox-addon xpcom

是否可以从Chrome注册表获取所有条目的列表及其实际物理映射?例如,我正在寻找这样的列表:

  

chrome://browser/content/browser.xul [实际物理路径]
  铬://browser/content/browser.js
  ...
  ...
  ...
  chrome://some_extension/content/overlay.xul jar:file:/// path / to / extension /

是否有一些数据结构将这些条目映射到chrome / src /目录源代码中?

1 个答案:

答案 0 :(得分:1)

映射由nsIChromeRegistry component执行,它处理所有清单文件并创建用于解析chrome://个URL的规则。这些规则没有公开,因为它们比你想象的要复杂得多。例如。 content instruction告诉chrome注册表如何解析以chrome://foo/content/开头的任何URL - 注册表只知道前缀而不知道单个文件。 localesskins的处理方式类似但有复杂性 - 可能有多个区域设置/皮肤以及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个实例,其中列出了每个有效URIchrome 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);
  }
}

尽管如此,解析清单是您在这种情况下必须自己做的事情,尤其是manifestcontentoverride行 - 总而言之,这些并不是一项简单的任务,特别是如果你正确地考虑了旗帜。