Bug 299730 - Chrome registry should be able to enumerate locales (for locale-switcher extension), and additional manifest features for forward/backward compatibility, r=darin a=asa

This commit is contained in:
bsmedberg%covad.net 2005-07-14 15:40:25 +00:00
Родитель ec03b5002b
Коммит 0fa430268b
4 изменённых файлов: 330 добавлений и 9 удалений

Просмотреть файл

@ -39,8 +39,9 @@
#include "nsIChromeRegistry.idl"
interface nsIURI;
interface nsIUTF8StringEnumerator;
[scriptable, uuid(717FA4AB-FD62-412b-AEF5-54A50B340449)]
[scriptable, uuid(94490b3f-f094-418e-b1b9-73878d29bff3)]
interface nsIToolkitChromeRegistry : nsIXULChromeRegistry
{
/**
@ -76,6 +77,11 @@ interface nsIToolkitChromeRegistry : nsIXULChromeRegistry
* call this method during the startup process.
*/
void checkForOSAccessibility();
/**
* Get a list of locales available for the specified package.
*/
nsIUTF8StringEnumerator getLocalesForPackage(in AUTF8String aPackage);
};
/**

Просмотреть файл

@ -73,6 +73,7 @@ REQUIRES = xpcom \
jar \
xulapp \
unicharutil \
update \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -47,6 +47,7 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsArrayEnumerator.h"
#include "nsStringEnumerator.h"
#include "nsEnumeratorUtils.h"
#include "nsCOMPtr.h"
#include "nsDOMError.h"
@ -95,8 +96,10 @@
#include "nsISimpleEnumerator.h"
#include "nsIStyleSheet.h"
#include "nsISupportsArray.h"
#include "nsIUpdateService.h" // for nsIVersionChecker
#include "nsIWindowMediator.h"
#include "nsIXPConnect.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
// keep all the RDF stuff together, in case we can remove it in the far future
@ -307,6 +310,16 @@ nsChromeRegistry::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI*
mArray.AppendElement(provider);
}
void
nsChromeRegistry::nsProviderArray::EnumerateToArray(nsCStringArray *a)
{
PRInt32 i = mArray.Count();
while (i--) {
ProviderEntry *entry = NS_REINTERPRET_CAST(ProviderEntry*, mArray[i]);
a->AppendCString(entry->provider);
}
}
void
nsChromeRegistry::nsProviderArray::Clear()
{
@ -741,6 +754,30 @@ nsChromeRegistry::GetSelectedLocale(const nsACString& aPackage, nsACString& aLoc
return NS_OK;
}
NS_IMETHODIMP
nsChromeRegistry::GetLocalesForPackage(const nsACString& aPackage,
nsIUTF8StringEnumerator* *aResult)
{
nsCStringArray *a = new nsCStringArray;
if (!a)
return NS_ERROR_OUT_OF_MEMORY;
PackageEntry* entry =
NS_STATIC_CAST(PackageEntry*, PL_DHashTableOperate(&mPackagesHash,
& aPackage,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
entry->locales.EnumerateToArray(a);
}
nsresult rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
if (NS_FAILED(rv))
delete a;
return rv;
}
NS_IMETHODIMP
nsChromeRegistry::GetStyleOverlays(nsIURI *aChromeURL,
nsISimpleEnumerator **aResult)
@ -1853,6 +1890,139 @@ CheckFlag(const nsSubstring& aFlag, const nsSubstring& aData, PRBool& aResult)
return PR_FALSE;
}
enum TriState {
eUnspecified,
eBad,
eOK
};
/**
* Check for a modifier flag of the following form:
* "flag=string"
* @param aFlag The flag to compare.
* @param aData The tokenized data to check; this is lowercased
* before being passed in.
* @param aValue The value that is expected.
* @param aResult If this is "ok" when passed in, this is left alone.
* Otherwise if the flag is found it is set to eBad or eOK.
* @return Whether the flag was handled.
*/
static PRBool
CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData,
const nsSubstring& aValue, TriState& aResult)
{
if (aData.Length() < aFlag.Length() + 1)
return PR_FALSE;
if (!StringBeginsWith(aData, aFlag))
return PR_FALSE;
if (aData[aFlag.Length()] != '=')
return PR_FALSE;
if (aResult != eOK) {
nsDependentSubstring testdata = Substring(aData, aFlag.Length() + 1);
if (testdata.Equals(aValue))
aResult = eOK;
else
aResult = eBad;
}
return PR_TRUE;
}
/**
* Check for a modifier flag of the following form:
* "flag=version"
* "flag<=version"
* "flag<version"
* "flag>=version"
* "flag>version"
* @param aFlag The flag to compare.
* @param aData The tokenized data to check; this is lowercased
* before being passed in.
* @param aValue The value that is expected.
* @param aChecker the version checker to use. If null, aResult will always
* be eBad.
* @param aResult If this is eOK when passed in, this is left alone.
* Otherwise if the flag is found it is set to eBad or eOK.
* @return Whether the flag was handled.
*/
#define COMPARE_EQ 1 << 0
#define COMPARE_LT 1 << 1
#define COMPARE_GT 1 << 2
static PRBool
CheckVersionFlag(const nsSubstring& aFlag, const nsSubstring& aData,
const nsSubstring& aValue, nsIVersionChecker* aChecker,
TriState& aResult)
{
if (! (aData.Length() > aFlag.Length() + 2))
return PR_FALSE;
if (!StringBeginsWith(aData, aFlag))
return PR_FALSE;
PRUint32 comparison;
nsAutoString testdata;
switch (aData[aFlag.Length()]) {
case '=':
comparison = COMPARE_EQ;
testdata = Substring(aData, aFlag.Length() + 1);
break;
case '<':
if (aData[aFlag.Length() + 1] == '=') {
comparison = COMPARE_EQ | COMPARE_LT;
testdata = Substring(aData, aFlag.Length() + 2);
}
else {
comparison = COMPARE_LT;
testdata = Substring(aData, aFlag.Length() + 1);
}
break;
case '>':
if (aData[aFlag.Length() + 1] == '=') {
comparison = COMPARE_EQ | COMPARE_GT;
testdata = Substring(aData, aFlag.Length() + 2);
}
else {
comparison = COMPARE_GT;
testdata = Substring(aData, aFlag.Length() + 1);
}
break;
default:
return PR_FALSE;
}
if (aResult != eOK) {
if (!aChecker) {
aResult = eBad;
}
else {
PRInt32 c;
nsresult rv = aChecker->Compare(aValue, testdata, &c);
if (NS_FAILED(rv)) {
aResult = eBad;
}
else {
if ((c == 0 && comparison & COMPARE_EQ) ||
(c < 0 && comparison & COMPARE_LT) ||
(c > 0 && comparison & COMPARE_GT))
aResult = eOK;
else
aResult = eBad;
}
}
}
return PR_TRUE;
}
nsresult
nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
nsILocalFile* aManifest,
@ -1860,8 +2030,10 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
{
nsresult rv;
NS_NAMED_LITERAL_STRING(kToken, "platform");
NS_NAMED_LITERAL_STRING(kPlatform, "platform");
NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers");
NS_NAMED_LITERAL_STRING(kApplication, "application");
NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
nsCOMPtr<nsIIOService> io (do_GetIOService());
if (!io) return NS_ERROR_FAILURE;
@ -1871,6 +2043,21 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIXPConnect> xpc (do_GetService("@mozilla.org/js/xpc/XPConnect;1"));
nsCOMPtr<nsIVersionChecker> vc (do_GetService("@mozilla.org/updates/version-checker;1"));
nsAutoString appID;
nsAutoString appVersion;
nsCOMPtr<nsIXULAppInfo> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
if (xapp) {
nsCAutoString s;
rv = xapp->GetID(s);
if (NS_SUCCEEDED(rv))
CopyUTF8toUTF16(s, appID);
rv = xapp->GetVersion(s);
if (NS_SUCCEEDED(rv))
CopyUTF8toUTF16(s, appVersion);
}
char *token;
char *newline = buf;
@ -1906,21 +2093,31 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
PRBool platform = PR_FALSE;
PRBool xpcNativeWrappers = PR_FALSE;
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace))) {
PRBool badFlag = PR_FALSE;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
!badFlag) {
NS_ConvertASCIItoUTF16 wtoken(token);
ToLowerCase(wtoken);
if (CheckFlag(kToken, wtoken, platform))
continue;
if (CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers))
if (CheckFlag(kPlatform, wtoken, platform) ||
CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers) ||
CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
"Warning: Unrecognized chrome registration modifier '%s'.",
token);
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
continue;
nsCOMPtr<nsIURI> resolved;
rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
getter_AddRefs(resolved));
@ -1965,6 +2162,29 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
continue;
}
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
PRBool badFlag = PR_FALSE;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
!badFlag) {
NS_ConvertASCIItoUTF16 wtoken(token);
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
"Warning: Unrecognized chrome registration modifier '%s'.",
token);
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
continue;
nsCOMPtr<nsIURI> resolved;
rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
getter_AddRefs(resolved));
@ -1990,6 +2210,29 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
continue;
}
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
PRBool badFlag = PR_FALSE;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
!badFlag) {
NS_ConvertASCIItoUTF16 wtoken(token);
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
"Warning: Unrecognized chrome registration modifier '%s'.",
token);
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
continue;
nsCOMPtr<nsIURI> resolved;
rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
getter_AddRefs(resolved));
@ -2019,6 +2262,29 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
continue;
}
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
PRBool badFlag = PR_FALSE;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
!badFlag) {
NS_ConvertASCIItoUTF16 wtoken(token);
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
"Warning: Unrecognized chrome registration modifier '%s'.",
token);
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
continue;
nsCOMPtr<nsIURI> baseuri, overlayuri;
rv = io->NewURI(nsDependentCString(base), nsnull, nsnull,
getter_AddRefs(baseuri));
@ -2040,6 +2306,29 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
continue;
}
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
PRBool badFlag = PR_FALSE;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
!badFlag) {
NS_ConvertASCIItoUTF16 wtoken(token);
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
"Warning: Unrecognized chrome registration modifier '%s'.",
token);
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
continue;
nsCOMPtr<nsIURI> baseuri, overlayuri;
rv = io->NewURI(nsDependentCString(base), nsnull, nsnull,
getter_AddRefs(baseuri));
@ -2065,6 +2354,29 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
continue;
}
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
PRBool badFlag = PR_FALSE;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
!badFlag) {
NS_ConvertASCIItoUTF16 wtoken(token);
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
"Warning: Unrecognized chrome registration modifier '%s'.",
token);
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
continue;
nsCOMPtr<nsIURI> chromeuri, resolveduri;
rv = io->NewURI(nsDependentCString(chrome), nsnull, nsnull,
getter_AddRefs(chromeuri));

Просмотреть файл

@ -148,13 +148,15 @@ public:
ANY = 2
};
ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
nsIURI* GetBase(const nsACString& aPreferred, MatchType aType);
const nsACString& GetSelected(const nsACString& aPreferred, MatchType aType);
void SetBase(const nsACString& aPreferred, nsIURI* base);
void SetBase(const nsACString& aProvider, nsIURI* base);
void EnumerateToArray(nsCStringArray *a);
void Clear();
private:
ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
nsVoidArray mArray;
};