зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
ec03b5002b
Коммит
0fa430268b
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче