зеркало из https://github.com/mozilla/gecko-dev.git
Bug 664917 Add Preferences API for getting default pref values r=roc, feedback=bz
This commit is contained in:
Родитель
4d1fc71a1e
Коммит
94f0f12f0c
|
@ -74,8 +74,8 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPREFSERVICE
|
||||
NS_DECL_NSIPREFSERVICEINTERNAL
|
||||
NS_FORWARD_NSIPREFBRANCH(mRootBranch->)
|
||||
NS_FORWARD_NSIPREFBRANCH2(mRootBranch->)
|
||||
NS_FORWARD_NSIPREFBRANCH(sRootBranch->)
|
||||
NS_FORWARD_NSIPREFBRANCH2(sRootBranch->)
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
Preferences();
|
||||
|
@ -110,7 +110,17 @@ public:
|
|||
static nsIPrefBranch2* GetRootBranch()
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), nsnull);
|
||||
return sPreferences->mRootBranch.get();
|
||||
return sRootBranch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns shared default pref branch instance.
|
||||
* NOTE: not addreffed.
|
||||
*/
|
||||
static nsIPrefBranch* GetDefaultRootBranch()
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), nsnull);
|
||||
return sDefaultRootBranch;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,6 +148,27 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets char type pref value directly. If failed, the get() of result
|
||||
* returns NULL. Even if succeeded but the result was empty string, the
|
||||
* get() does NOT return NULL. So, you can check whether the method
|
||||
* succeeded or not by:
|
||||
*
|
||||
* nsAdoptingString value = Prefereces::GetString("foo.bar");
|
||||
* if (!value) {
|
||||
* // failed
|
||||
* }
|
||||
*
|
||||
* Be aware. If you wrote as:
|
||||
*
|
||||
* nsAutoString value = Preferences::GetString("foo.bar");
|
||||
* if (!value.get()) {
|
||||
* // the condition is always FALSE!!
|
||||
* }
|
||||
*
|
||||
* The value.get() doesn't return NULL. You must use nsAdoptingString when
|
||||
* you need to check whether it was failure or not.
|
||||
*/
|
||||
static nsAdoptingCString GetCString(const char* aPref);
|
||||
static nsAdoptingString GetString(const char* aPref);
|
||||
static nsAdoptingCString GetLocalizedCString(const char* aPref);
|
||||
|
@ -251,6 +282,65 @@ public:
|
|||
const char* aPref,
|
||||
PRUint32 aDefault = 0);
|
||||
|
||||
/**
|
||||
* Gets the default bool, int or uint value of the pref.
|
||||
* The result is raw result of nsIPrefBranch::Get*Pref().
|
||||
* If the pref could have any value, you needed to use these methods.
|
||||
* If not so, you could use below methods.
|
||||
*/
|
||||
static nsresult GetDefaultBool(const char* aPref, PRBool* aResult);
|
||||
static nsresult GetDefaultInt(const char* aPref, PRInt32* aResult);
|
||||
static nsresult GetDefaultUint(const char* aPref, PRUint32* aResult)
|
||||
{
|
||||
return GetDefaultInt(aPref, reinterpret_cast<PRInt32*>(aResult));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default bool, int or uint value of the pref directly.
|
||||
* You can set an invalid value of the pref to aFailedResult. If these
|
||||
* methods failed to get the default value, they would return the
|
||||
* aFailedResult value.
|
||||
*/
|
||||
static PRBool GetDefaultBool(const char* aPref, PRBool aFailedResult)
|
||||
{
|
||||
PRBool result;
|
||||
return NS_SUCCEEDED(GetDefaultBool(aPref, &result)) ? result :
|
||||
aFailedResult;
|
||||
}
|
||||
static PRInt32 GetDefaultInt(const char* aPref, PRInt32 aFailedResult)
|
||||
{
|
||||
PRInt32 result;
|
||||
return NS_SUCCEEDED(GetDefaultInt(aPref, &result)) ? result : aFailedResult;
|
||||
}
|
||||
static PRUint32 GetDefaultUint(const char* aPref, PRUint32 aFailedResult)
|
||||
{
|
||||
return static_cast<PRUint32>(
|
||||
GetDefaultInt(aPref, static_cast<PRInt32>(aFailedResult)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default value of the char type pref.
|
||||
* If the get() of the result returned NULL, that meant the value didn't
|
||||
* have default value.
|
||||
*
|
||||
* See the comment at definition at GetString() and GetCString() for more
|
||||
* details of the result.
|
||||
*/
|
||||
static nsAdoptingString GetDefaultString(const char* aPref);
|
||||
static nsAdoptingCString GetDefaultCString(const char* aPref);
|
||||
static nsAdoptingString GetDefaultLocalizedString(const char* aPref);
|
||||
static nsAdoptingCString GetDefaultLocalizedCString(const char* aPref);
|
||||
|
||||
static nsresult GetDefaultCString(const char* aPref, nsACString* aResult);
|
||||
static nsresult GetDefaultString(const char* aPref, nsAString* aResult);
|
||||
static nsresult GetDefaultLocalizedCString(const char* aPref,
|
||||
nsACString* aResult);
|
||||
static nsresult GetDefaultLocalizedString(const char* aPref,
|
||||
nsAString* aResult);
|
||||
|
||||
static nsresult GetDefaultComplex(const char* aPref, const nsIID &aType,
|
||||
void** aResult);
|
||||
|
||||
protected:
|
||||
nsresult NotifyServiceObservers(const char *aSubject);
|
||||
nsresult UseDefaultPrefFile();
|
||||
|
@ -262,10 +352,12 @@ protected:
|
|||
nsresult MakeBackupPrefFile(nsIFile *aFile);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPrefBranch2> mRootBranch;
|
||||
nsCOMPtr<nsIFile> mCurrentFile;
|
||||
|
||||
static Preferences* sPreferences;
|
||||
static nsIPrefBranch2* sRootBranch;
|
||||
// NOTE: default branch doesn't return nsIPrefBranch2 interface at query.
|
||||
static nsIPrefBranch* sDefaultRootBranch;
|
||||
static PRBool sShutdown;
|
||||
|
||||
/**
|
||||
|
|
|
@ -88,6 +88,8 @@ static nsresult pref_InitInitialObjects(void);
|
|||
static nsresult pref_LoadPrefsInDirList(const char *listId);
|
||||
|
||||
Preferences* Preferences::sPreferences = nsnull;
|
||||
nsIPrefBranch2* Preferences::sRootBranch = nsnull;
|
||||
nsIPrefBranch* Preferences::sDefaultRootBranch = nsnull;
|
||||
PRBool Preferences::sShutdown = PR_FALSE;
|
||||
|
||||
class ValueObserverHashKey : public PLDHashEntryHdr {
|
||||
|
@ -223,9 +225,16 @@ Preferences::InitStaticMembers(PRBool aForService)
|
|||
return sPreferences != nsnull;
|
||||
}
|
||||
|
||||
sRootBranch = new nsPrefBranch("", PR_FALSE);
|
||||
NS_ADDREF(sRootBranch);
|
||||
sDefaultRootBranch = new nsPrefBranch("", PR_TRUE);
|
||||
NS_ADDREF(sDefaultRootBranch);
|
||||
|
||||
sPreferences = new Preferences();
|
||||
NS_ADDREF(sPreferences);
|
||||
if (NS_FAILED(sPreferences->Init()) || !sPreferences->mRootBranch) {
|
||||
|
||||
if (NS_FAILED(sPreferences->Init())) {
|
||||
// The singleton instance will delete sRootBranch and sDefaultRootBranch.
|
||||
NS_RELEASE(sPreferences);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -274,6 +283,9 @@ Preferences::~Preferences()
|
|||
delete gCacheData;
|
||||
gCacheData = nsnull;
|
||||
|
||||
NS_RELEASE(sRootBranch);
|
||||
NS_RELEASE(sDefaultRootBranch);
|
||||
|
||||
sPreferences = nsnull;
|
||||
|
||||
PREF_Cleanup();
|
||||
|
@ -306,12 +318,6 @@ NS_INTERFACE_MAP_END
|
|||
nsresult
|
||||
Preferences::Init()
|
||||
{
|
||||
nsPrefBranch *rootBranch = new nsPrefBranch("", PR_FALSE);
|
||||
if (!rootBranch)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mRootBranch = (nsIPrefBranch2 *)rootBranch;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = PREF_Init();
|
||||
|
@ -342,7 +348,7 @@ Preferences::Init()
|
|||
* category which will do the rest.
|
||||
*/
|
||||
|
||||
rv = mRootBranch->GetCharPref("general.config.filename", getter_Copies(lockFileName));
|
||||
rv = sRootBranch->GetCharPref("general.config.filename", getter_Copies(lockFileName));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
NS_CreateServicesFromCategory("pref-config-startup",
|
||||
static_cast<nsISupports *>(static_cast<void *>(this)),
|
||||
|
@ -563,7 +569,7 @@ Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
|
|||
rv = CallQueryInterface(prefBranch, _retval);
|
||||
} else {
|
||||
// special case caching the default root
|
||||
rv = CallQueryInterface(mRootBranch, _retval);
|
||||
rv = CallQueryInterface(sRootBranch, _retval);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -571,15 +577,16 @@ Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
|
|||
NS_IMETHODIMP
|
||||
Preferences::GetDefaultBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!aPrefRoot || !aPrefRoot[0]) {
|
||||
return CallQueryInterface(sDefaultRootBranch, _retval);
|
||||
}
|
||||
|
||||
// TODO: - cache this stuff and allow consumers to share branches (hold weak references I think)
|
||||
nsPrefBranch* prefBranch = new nsPrefBranch(aPrefRoot, PR_TRUE);
|
||||
if (!prefBranch)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = CallQueryInterface(prefBranch, _retval);
|
||||
return rv;
|
||||
return CallQueryInterface(prefBranch, _retval);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1144,7 +1151,7 @@ Preferences::GetBool(const char* aPref, PRBool* aResult)
|
|||
{
|
||||
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->GetBoolPref(aPref, aResult);
|
||||
return sRootBranch->GetBoolPref(aPref, aResult);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1153,7 +1160,7 @@ Preferences::GetInt(const char* aPref, PRInt32* aResult)
|
|||
{
|
||||
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->GetIntPref(aPref, aResult);
|
||||
return sRootBranch->GetIntPref(aPref, aResult);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1181,8 +1188,7 @@ Preferences::GetCString(const char* aPref, nsACString* aResult)
|
|||
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
nsCAutoString result;
|
||||
nsresult rv =
|
||||
sPreferences->mRootBranch->GetCharPref(aPref, getter_Copies(result));
|
||||
nsresult rv = sRootBranch->GetCharPref(aPref, getter_Copies(result));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aResult = result;
|
||||
}
|
||||
|
@ -1196,8 +1202,7 @@ Preferences::GetString(const char* aPref, nsAString* aResult)
|
|||
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
nsCAutoString result;
|
||||
nsresult rv =
|
||||
sPreferences->mRootBranch->GetCharPref(aPref, getter_Copies(result));
|
||||
nsresult rv = sRootBranch->GetCharPref(aPref, getter_Copies(result));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CopyUTF8toUTF16(result, *aResult);
|
||||
}
|
||||
|
@ -1242,7 +1247,7 @@ Preferences::GetLocalizedString(const char* aPref, nsAString* aResult)
|
|||
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
|
||||
nsresult rv = sPreferences->mRootBranch->GetComplexValue(aPref,
|
||||
nsresult rv = sRootBranch->GetComplexValue(aPref,
|
||||
NS_GET_IID(nsIPrefLocalizedString),
|
||||
getter_AddRefs(prefLocalString));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1257,7 +1262,7 @@ nsresult
|
|||
Preferences::GetComplex(const char* aPref, const nsIID &aType, void** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->GetComplexValue(aPref, aType, aResult);
|
||||
return sRootBranch->GetComplexValue(aPref, aType, aResult);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1265,7 +1270,7 @@ nsresult
|
|||
Preferences::SetCString(const char* aPref, const char* aValue)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->SetCharPref(aPref, aValue);
|
||||
return sRootBranch->SetCharPref(aPref, aValue);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1296,7 +1301,7 @@ nsresult
|
|||
Preferences::SetBool(const char* aPref, PRBool aValue)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->SetBoolPref(aPref, aValue);
|
||||
return sRootBranch->SetBoolPref(aPref, aValue);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1304,7 +1309,7 @@ nsresult
|
|||
Preferences::SetInt(const char* aPref, PRInt32 aValue)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->SetIntPref(aPref, aValue);
|
||||
return sRootBranch->SetIntPref(aPref, aValue);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1313,7 +1318,7 @@ Preferences::SetComplex(const char* aPref, const nsIID &aType,
|
|||
nsISupports* aValue)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->SetComplexValue(aPref, aType, aValue);
|
||||
return sRootBranch->SetComplexValue(aPref, aType, aValue);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1321,7 +1326,7 @@ nsresult
|
|||
Preferences::ClearUser(const char* aPref)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->ClearUserPref(aPref);
|
||||
return sRootBranch->ClearUserPref(aPref);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1330,8 +1335,7 @@ Preferences::HasUserValue(const char* aPref)
|
|||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), PR_FALSE);
|
||||
PRBool hasUserValue;
|
||||
nsresult rv =
|
||||
sPreferences->mRootBranch->PrefHasUserValue(aPref, &hasUserValue);
|
||||
nsresult rv = sRootBranch->PrefHasUserValue(aPref, &hasUserValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -1344,7 +1348,7 @@ Preferences::AddStrongObserver(nsIObserver* aObserver,
|
|||
const char* aPref)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->AddObserver(aPref, aObserver, PR_FALSE);
|
||||
return sRootBranch->AddObserver(aPref, aObserver, PR_FALSE);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1353,7 +1357,7 @@ Preferences::AddWeakObserver(nsIObserver* aObserver,
|
|||
const char* aPref)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->AddObserver(aPref, aObserver, PR_TRUE);
|
||||
return sRootBranch->AddObserver(aPref, aObserver, PR_TRUE);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1365,7 +1369,7 @@ Preferences::RemoveObserver(nsIObserver* aObserver,
|
|||
return NS_OK; // Observers have been released automatically.
|
||||
}
|
||||
NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE);
|
||||
return sPreferences->mRootBranch->RemoveObserver(aPref, aObserver);
|
||||
return sRootBranch->RemoveObserver(aPref, aObserver);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1528,4 +1532,122 @@ Preferences::AddUintVarCache(PRUint32* aCache,
|
|||
return RegisterCallback(UintVarChanged, aPref, data);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Preferences::GetDefaultBool(const char* aPref, PRBool* aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sDefaultRootBranch->GetBoolPref(aPref, aResult);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Preferences::GetDefaultInt(const char* aPref, PRInt32* aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sDefaultRootBranch->GetIntPref(aPref, aResult);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Preferences::GetDefaultCString(const char* aPref, nsACString* aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
nsCAutoString result;
|
||||
nsresult rv = sDefaultRootBranch->GetCharPref(aPref, getter_Copies(result));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aResult = result;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Preferences::GetDefaultString(const char* aPref, nsAString* aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
nsCAutoString result;
|
||||
nsresult rv = sDefaultRootBranch->GetCharPref(aPref, getter_Copies(result));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CopyUTF8toUTF16(result, *aResult);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Preferences::GetDefaultLocalizedCString(const char* aPref,
|
||||
nsACString* aResult)
|
||||
{
|
||||
nsAutoString result;
|
||||
nsresult rv = GetDefaultLocalizedString(aPref, &result);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CopyUTF16toUTF8(result, *aResult);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Preferences::GetDefaultLocalizedString(const char* aPref,
|
||||
nsAString* aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
|
||||
nsresult rv =
|
||||
sDefaultRootBranch->GetComplexValue(aPref,
|
||||
NS_GET_IID(nsIPrefLocalizedString),
|
||||
getter_AddRefs(prefLocalString));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL");
|
||||
prefLocalString->GetData(getter_Copies(*aResult));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsAdoptingString
|
||||
Preferences::GetDefaultString(const char* aPref)
|
||||
{
|
||||
nsAdoptingString result;
|
||||
GetDefaultString(aPref, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
nsAdoptingCString
|
||||
Preferences::GetDefaultCString(const char* aPref)
|
||||
{
|
||||
nsAdoptingCString result;
|
||||
GetDefaultCString(aPref, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
nsAdoptingString
|
||||
Preferences::GetDefaultLocalizedString(const char* aPref)
|
||||
{
|
||||
nsAdoptingString result;
|
||||
GetDefaultLocalizedString(aPref, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
nsAdoptingCString
|
||||
Preferences::GetDefaultLocalizedCString(const char* aPref)
|
||||
{
|
||||
nsAdoptingCString result;
|
||||
GetDefaultLocalizedCString(aPref, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Preferences::GetDefaultComplex(const char* aPref, const nsIID &aType,
|
||||
void** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
return sDefaultRootBranch->GetComplexValue(aPref, aType, aResult);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
Загрузка…
Ссылка в новой задаче