Compare commits

...
Author SHA1 Message Date
Moonchild 2694995e52 Merge branch 'master' into 1210 2022-05-21 16:38:37 +00:00
Moonchild f532bbd7af Issue #1210 - Simplify the implementation of mozILocaleService.
Combine both GetAppLocale methods and Update
mozILocaleService.getAppLocales to avoid use of jsapi.
2022-05-21 09:18:08 +00:00
Moonchild e4bf79f912 Issue #1210 - Expose mozILocaleService Cc interface 2022-05-20 01:02:52 +00:00
Moonchild e1f95393a1 Issue #1210 - Expose getAppLocales() to Chrome and XBL
This allows JS to access the application locales.
2022-05-19 22:37:20 +00:00
Moonchild b2eff33c92 Issue #1210 - Introduce an internal API to get configured application locales.
en-US will always be added as a fallback, to make things simpler down the line
and avoid error checking all over the place.
2022-05-19 21:57:58 +00:00
10 changed files with 290 additions and 0 deletions

No files matched your search

+2
View File
@@ -25,6 +25,7 @@
#include "mozilla/LookAndFeel.h"
#include "mozilla/Unused.h"
#include "mozilla/intl/LocaleService.h"
#include "nsICommandLine.h"
#include "nsILocaleService.h"
@@ -385,6 +386,7 @@ nsresult nsChromeRegistryChrome::UpdateSelectedLocale()
NS_ASSERTION(obsSvc, "Couldn't get observer service.");
obsSvc->NotifyObservers((nsIChromeRegistry*) this,
"selected-locale-has-changed", nullptr);
mozilla::intl::LocaleService::GetInstance()->Refresh();
}
}
+12
View File
@@ -49,6 +49,7 @@
#include "nsNetUtil.h"
#include "nsVariant.h"
#include "nsPrintfCString.h"
#include "mozilla/intl/LocaleService.h"
// Helper Classes
#include "nsJSUtils.h"
@@ -14794,6 +14795,17 @@ nsGlobalWindow::CreateWorklet(ErrorResult& aRv)
return worklet.forget();
}
void
nsGlobalWindow::GetAppLocales(nsTArray<nsString>& aLocales)
{
nsTArray<nsCString> appLocales;
mozilla::intl::LocaleService::GetInstance()->GetAppLocales(appLocales);
for (uint32_t i = 0; i < appLocales.Length(); i++) {
aLocales.AppendElement(NS_ConvertUTF8toUTF16(appLocales[i]));
}
}
template class nsPIDOMWindow<mozIDOMWindowProxy>;
template class nsPIDOMWindow<mozIDOMWindow>;
template class nsPIDOMWindow<nsISupports>;
+3
View File
@@ -897,6 +897,9 @@ public:
already_AddRefed<mozilla::dom::Worklet>
CreateWorklet(mozilla::ErrorResult& aRv);
void
GetAppLocales(nsTArray<nsString>& aLocales);
protected:
bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
nsIPrincipal& aSubjectPrincipal,
+15
View File
@@ -486,3 +486,18 @@ callback IdleRequestCallback = void (IdleDeadline deadline);
partial interface Window {
[ChromeOnly] readonly attribute boolean isSecureContextIfOpenerIgnored;
};
partial interface Window {
/**
* Returns a list of locales that the application should be localized to.
*
* The result is a sorted list of valid locale IDs and it should be
* used for all APIs that accept list of locales, like ECMA402 and L10n APIs.
*
* This API always returns at least one locale.
*
* Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
*/
[Func="IsChromeOrXBL"]
sequence<DOMString> getAppLocales();
};
+3
View File
@@ -44,6 +44,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsEntityConverter)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSaveAsCharset)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeNormalizer)
NS_DEFINE_NAMED_CID(MOZ_LOCALESERVICE_CID);
NS_DEFINE_NAMED_CID(NS_LBRK_CID);
NS_DEFINE_NAMED_CID(NS_WBRK_CID);
NS_DEFINE_NAMED_CID(NS_SEMANTICUNITSCANNER_CID);
@@ -73,6 +74,7 @@ NS_DEFINE_NAMED_CID(NS_DATETIMEFORMAT_CID);
#endif
static const mozilla::Module::CIDEntry kIntlCIDs[] = {
{ &kMOZ_LOCALESERVICE_CID, false, nullptr, mozilla::intl::LocaleServiceConstructor },
{ &kNS_LBRK_CID, false, nullptr, nsJISx4051LineBreakerConstructor },
{ &kNS_WBRK_CID, false, nullptr, nsSampleWordBreakerConstructor },
{ &kNS_SEMANTICUNITSCANNER_CID, false, nullptr, nsSemanticUnitScannerConstructor },
@@ -104,6 +106,7 @@ static const mozilla::Module::CIDEntry kIntlCIDs[] = {
};
static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
{ MOZ_LOCALESERVICE_CONTRACTID, &kMOZ_LOCALESERVICE_CID },
{ NS_LBRK_CONTRACTID, &kNS_LBRK_CID },
{ NS_WBRK_CONTRACTID, &kNS_WBRK_CID },
{ NS_SEMANTICUNITSCANNER_CONTRACTID, &kNS_SEMANTICUNITSCANNER_CID },
+105
View File
@@ -0,0 +1,105 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LocaleService.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Services.h"
#include "nsIObserverService.h"
#include "nsIToolkitChromeRegistry.h"
using namespace mozilla::intl;
NS_IMPL_ISUPPORTS(LocaleService, mozILocaleService)
mozilla::StaticRefPtr<LocaleService> LocaleService::sInstance;
/**
* This function performs the actual language negotiation for the API.
*
* Currently it collects the locale ID used by nsChromeRegistry and
* adds hardcoded "en-US" locale as a fallback.
*/
static void
ReadAppLocales(nsTArray<nsCString>& aRetVal)
{
nsAutoCString uaLangTag;
nsCOMPtr<nsIToolkitChromeRegistry> cr =
mozilla::services::GetToolkitChromeRegistryService();
if (cr) {
cr->GetSelectedLocale(NS_LITERAL_CSTRING("global"), true, uaLangTag);
}
if (!uaLangTag.IsEmpty()) {
aRetVal.AppendElement(uaLangTag);
}
if (!uaLangTag.EqualsLiteral("en-US")) {
aRetVal.AppendElement(NS_LITERAL_CSTRING("en-US"));
}
}
LocaleService*
LocaleService::GetInstance()
{
if (!sInstance) {
sInstance = new LocaleService();
ClearOnShutdown(&sInstance);
}
return sInstance;
}
void
LocaleService::GetAppLocales(nsTArray<nsCString>& aRetVal)
{
if (mAppLocales.IsEmpty()) {
ReadAppLocales(mAppLocales);
}
aRetVal = mAppLocales;
}
void
LocaleService::Refresh()
{
nsTArray<nsCString> newLocales;
ReadAppLocales(newLocales);
if (mAppLocales != newLocales) {
mAppLocales = Move(newLocales);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->NotifyObservers(nullptr, "intl:app-locales-changed", nullptr);
}
}
}
/**
* mozILocaleService methods
*/
NS_IMETHODIMP
LocaleService::GetAppLocales(uint32_t* aCount, char*** aOutArray)
{
if (mAppLocales.IsEmpty()) {
ReadAppLocales(mAppLocales);
}
*aCount = mAppLocales.Length();
*aOutArray = static_cast<char**>(moz_xmalloc(*aCount * sizeof(char*)));
for (uint32_t i = 0; i < *aCount; i++) {
(*aOutArray)[i] = moz_xstrdup(mAppLocales[i].get());
}
return NS_OK;
}
NS_IMETHODIMP
LocaleService::GetAppLocale(nsACString& aRetVal)
{
if (mAppLocales.IsEmpty()) {
ReadAppLocales(mAppLocales);
}
aRetVal = mAppLocales[0];
return NS_OK;
}
+88
View File
@@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_intl_LocaleService_h__
#define mozilla_intl_LocaleService_h__
#include "mozilla/StaticPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozILocaleService.h"
namespace mozilla {
namespace intl {
/**
* LocaleService is a manager of language negotiation in Gecko.
*
* It's intended to be the core place for collecting available and
* requested languages and negotiating them to produce a fallback
* chain of locales for the application.
*/
class LocaleService : public mozILocaleService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZILOCALESERVICE
/**
* Create (if necessary) and return a raw pointer to the singleton instance.
* Use this accessor in C++ code that just wants to call a method on the
* instance, but does not need to hold a reference, as in
* nsAutoCString str;
* LocaleService::GetInstance()->GetAppLocale(str);
*/
static LocaleService* GetInstance();
/**
* Return an addRef'd pointer to the singleton instance. This is used by the
* XPCOM constructor that exists to support usage from JS.
*/
static already_AddRefed<LocaleService> GetInstanceAddRefed()
{
return RefPtr<LocaleService>(GetInstance()).forget();
}
/**
* Returns a list of locales that the application should be localized to.
*
* The result is a sorted list of valid locale IDs and it should be
* used for all APIs that accept list of locales, like ECMA402 and L10n APIs.
*
* This API always returns at least one locale.
*
* Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
*
* Usage:
* nsTArray<nsCString> appLocales;
* LocaleService::GetInstance()->GetAppLocales(appLocales);
*
* (See mozILocaleService.idl for a JS-callable version of this.)
*/
void GetAppLocales(nsTArray<nsCString>& aRetVal);
/**
* Triggers a refresh of the language negotiation process.
*
* If the result differs from the previous list, it will additionally
* trigger a global event "intl:app-locales-changed".
*/
void Refresh();
protected:
nsTArray<nsCString> mAppLocales;
private:
virtual ~LocaleService() {};
static StaticRefPtr<LocaleService> sInstance;
};
} // intl
} // namespace mozilla
#endif /* mozilla_intl_LocaleService_h__ */
+6
View File
@@ -15,6 +15,7 @@ else:
DIRS += ['unix']
XPIDL_SOURCES += [
'mozILocaleService.idl',
'nsICollation.idl',
'nsILocale.idl',
'nsILocaleService.idl',
@@ -35,7 +36,12 @@ EXPORTS += [
'nsWin32Locale.h',
]
EXPORTS.mozilla.intl += [
'LocaleService.h'
]
UNIFIED_SOURCES += [
'LocaleService.cpp',
'nsCollation.cpp',
'nsIDateTimeFormat.cpp',
'nsLanguageAtomService.cpp',
+48
View File
@@ -0,0 +1,48 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
%{C++
// Define Contractid and CID
#define MOZ_LOCALESERVICE_CID \
{ 0x92735ff4, 0x6384, 0x4ad6, { 0x85, 0x08, 0x75, 0x70, 0x10, 0xe1, 0x49, 0xee } }
#define MOZ_LOCALESERVICE_CONTRACTID "@mozilla.org/intl/localeservice;1"
%}
[scriptable, uuid(C27F8983-B48B-4D1A-92D7-FEB8106F212D)]
interface mozILocaleService : nsISupports
{
/**
* Returns a list of locales that the application should be localized to.
*
* The result is a sorted list of valid locale IDs and it should be
* used for all APIs that accept list of locales, like ECMA402 and L10n APIs.
*
* This API always returns at least one locale.
*
* Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
*
* (See LocaleService.h for a more C++-friendly version of this.)
*/
void getAppLocales([optional] out unsigned long aCount,
[retval, array, size_is(aCount)] out string aLocales);
/**
* Returns the best locale that the application should be localized to.
*
* The result is a valid locale ID and it should be
* used for all APIs that do not handle language negotiation.
*
* Where possible, getAppLocales() should be preferred over this API and
* all callsites should handle some form of "best effort" language
* negotiation to respect user preferences in case the use case does
* not have data for the first locale in the list.
*
* Example: "zh-Hans-HK"
*/
ACString getAppLocale();
};
+8
View File
@@ -14,6 +14,7 @@
#include "nsIServiceManager.h"
#include "nsLanguageAtomService.h"
#include "nsPlatformCharset.h"
#include "LocaleService.h"
#if defined(XP_MACOSX)
#define USE_MAC_LOCALE
@@ -61,6 +62,13 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationFactory)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLanguageAtomService)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPlatformCharset, Init)
namespace mozilla {
namespace intl {
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(LocaleService,
LocaleService::GetInstanceAddRefed)
}
}
#ifdef XP_WIN
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationWin)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDateTimeFormatWin)