зеркало из https://github.com/mozilla/gecko-dev.git
Allow a manifest to register contracts and cids in any order, by deferring processing of contracts until the manifest is completely parsed. This is needed for extension author sanity, and also because jar.mn packaging doesn't place registration lines in order by default.
This commit is contained in:
Родитель
8146fde6ce
Коммит
6a6ee9e7df
|
@ -84,6 +84,8 @@ struct ManifestDirective
|
|||
(nsChromeRegistry::ManifestProcessingContext& cx,
|
||||
int lineno, char *const *argv,
|
||||
bool platform, bool contentaccessible);
|
||||
|
||||
bool isContract;
|
||||
};
|
||||
static const ManifestDirective kParsingTable[] = {
|
||||
{ "binary-component", 1, true, false, false,
|
||||
|
@ -91,7 +93,7 @@ static const ManifestDirective kParsingTable[] = {
|
|||
{ "component", 2, true, false, false,
|
||||
&nsComponentManagerImpl::ManifestComponent, NULL },
|
||||
{ "contract", 2, true, false, false,
|
||||
&nsComponentManagerImpl::ManifestContract, NULL },
|
||||
&nsComponentManagerImpl::ManifestContract, NULL, true},
|
||||
{ "category", 3, true, false, false,
|
||||
&nsComponentManagerImpl::ManifestCategory, NULL },
|
||||
{ "content", 2, true, true, true,
|
||||
|
@ -331,6 +333,16 @@ CheckVersionFlag(const nsString& aFlag, const nsString& aData,
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct CachedDirective
|
||||
{
|
||||
int lineno;
|
||||
char* argv[4];
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
|
||||
bool aChromeOnly)
|
||||
|
@ -393,6 +405,10 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
|
|||
gtk_minor_version);
|
||||
#endif
|
||||
|
||||
// Because contracts must be registered after CIDs, we save and process them
|
||||
// at the end.
|
||||
nsTArray<CachedDirective> contracts;
|
||||
|
||||
char *token;
|
||||
char *newline = buf;
|
||||
PRUint32 line = 0;
|
||||
|
@ -479,8 +495,22 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
|
|||
(nsChromeRegistry::gChromeRegistry->*(directive->regfunc))
|
||||
(chromecx, line, argv, platform, contentAccessible);
|
||||
}
|
||||
else if (!aChromeOnly)
|
||||
(nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
|
||||
(mgrcx, line, argv);
|
||||
else if (!aChromeOnly) {
|
||||
if (directive->isContract) {
|
||||
CachedDirective* cd = contracts.AppendElement();
|
||||
cd->lineno = line;
|
||||
cd->argv[0] = argv[0];
|
||||
cd->argv[1] = argv[1];
|
||||
}
|
||||
else
|
||||
(nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
|
||||
(mgrcx, line, argv);
|
||||
}
|
||||
}
|
||||
|
||||
for (PRInt32 i = 0; i < contracts.Length(); ++i) {
|
||||
CachedDirective& d = contracts[i];
|
||||
nsComponentManagerImpl::gComponentManager->ManifestContract
|
||||
(mgrcx, d.lineno, d.argv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,6 +235,20 @@ _PlatformDeinitProfiler()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ScopedLogging
|
||||
{
|
||||
public:
|
||||
ScopedLogging()
|
||||
{
|
||||
NS_LogInit();
|
||||
}
|
||||
|
||||
~ScopedLogging()
|
||||
{
|
||||
NS_LogTerm();
|
||||
}
|
||||
};
|
||||
|
||||
class ScopedXPCOM : public nsIDirectoryServiceProvider2
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -44,6 +44,7 @@
|
|||
#include "nsCOMArray.h"
|
||||
#include "nsArrayEnumerator.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIComponentRegistrar.h"
|
||||
|
||||
#define SERVICE_A_CONTRACT_ID "@mozilla.org/RegTestServiceA;1"
|
||||
#define SERVICE_B_CONTRACT_ID "@mozilla.org/RegTestServiceB;1"
|
||||
|
@ -132,6 +133,30 @@ nsresult TestRegular()
|
|||
kCoreServiceA_CID, kExtServiceA_CID);
|
||||
}
|
||||
|
||||
bool TestContractFirst()
|
||||
{
|
||||
nsCOMPtr<nsIComponentRegistrar> r;
|
||||
NS_GetComponentRegistrar(getter_AddRefs(r));
|
||||
|
||||
nsCID* cid = NULL;
|
||||
nsresult rv = r->ContractIDToCID("@mozilla.org/RegTestOrderC;1", &cid);
|
||||
if (NS_FAILED(rv)) {
|
||||
fail("RegTestOrderC: contract not registered");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCID goodcid;
|
||||
goodcid.Parse("{ada15884-bb89-473c-8b50-dcfbb8447ff4}");
|
||||
|
||||
if (!goodcid.Equals(*cid)) {
|
||||
fail("RegTestOrderC: CID doesn't match");
|
||||
return false;
|
||||
}
|
||||
|
||||
passed("RegTestOrderC");
|
||||
return true;
|
||||
}
|
||||
|
||||
static already_AddRefed<nsILocalFile>
|
||||
GetRegDirectory(const char* basename, const char* dirname)
|
||||
{
|
||||
|
@ -145,6 +170,8 @@ GetRegDirectory(const char* basename, const char* dirname)
|
|||
return f.forget();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
|
@ -153,6 +180,7 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
ScopedLogging logging;
|
||||
|
||||
const char *regPath = argv[1];
|
||||
XRE_AddComponentLocation(NS_COMPONENT_LOCATION,
|
||||
|
@ -167,5 +195,8 @@ int main(int argc, char** argv)
|
|||
if (NS_FAILED(TestRegular()))
|
||||
rv = 1;
|
||||
|
||||
if (!TestContractFirst())
|
||||
rv = 1;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
component {56ab1cd4-ac44-4f86-8104-171f8b8f2fc7} component.js
|
||||
contract @mozilla.org/RegTestServiceA;1 {56ab1cd4-ac44-4f86-8104-171f8b8f2fc7}
|
||||
|
||||
contract @mozilla.org/RegTestOrderC;1 {ada15884-bb89-473c-8b50-dcfbb8447ff4}
|
||||
component {ada15884-bb89-473c-8b50-dcfbb8447ff4} missing.js
|
||||
|
|
Загрузка…
Ссылка в новой задаче