summaryrefslogtreecommitdiff
path: root/intl
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2022-05-19 21:57:58 +0000
committerMoonchild <moonchild@palemoon.org>2022-05-19 21:57:58 +0000
commitb2eff33c9258cb5e0ce754f5a675885222212dba (patch)
tree3e8d22ab8a74e168b427821dbef9d7ef02431f12 /intl
parent51117c2b62ff7cef626addb6416336f76d54d97e (diff)
downloaduxp-b2eff33c9258cb5e0ce754f5a675885222212dba.tar.gz
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.
Diffstat (limited to 'intl')
-rw-r--r--intl/locale/LocaleService.cpp80
-rw-r--r--intl/locale/LocaleService.h82
-rw-r--r--intl/locale/moz.build5
3 files changed, 167 insertions, 0 deletions
diff --git a/intl/locale/LocaleService.cpp b/intl/locale/LocaleService.cpp
new file mode 100644
index 0000000000..55542dc1a9
--- /dev/null
+++ b/intl/locale/LocaleService.cpp
@@ -0,0 +1,80 @@
+/* -*- 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;
+
+/**
+ * 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"));
+ }
+}
+
+mozilla::StaticAutoPtr<LocaleService> LocaleService::sInstance;
+
+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::GetAppLocale(nsACString& aRetVal)
+{
+ if (mAppLocales.IsEmpty()) {
+ ReadAppLocales(mAppLocales);
+ }
+ aRetVal = mAppLocales[0];
+}
+
+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);
+ }
+ }
+} \ No newline at end of file
diff --git a/intl/locale/LocaleService.h b/intl/locale/LocaleService.h
new file mode 100644
index 0000000000..e5228418c4
--- /dev/null
+++ b/intl/locale/LocaleService.h
@@ -0,0 +1,82 @@
+/* -*- 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"
+
+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:
+ static LocaleService* GetInstance();
+
+ /**
+ * 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);
+ */
+ void GetAppLocales(nsTArray<nsCString>& aRetVal);
+
+ /**
+ * Returns the best locale that the application should be localized to.
+ *
+ * The result is a valid locale IDs 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"
+ *
+ * Usage:
+ * nsAutoCString appLocale;
+ * LocaleService::GetInstance()->GetAppLocale(appLocale);
+ */
+ void GetAppLocale(nsACString& 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:
+ static StaticAutoPtr<LocaleService> sInstance;
+};
+
+} // intl
+} // namespace mozilla
+
+#endif /* mozilla_intl_LocaleService_h__ */
diff --git a/intl/locale/moz.build b/intl/locale/moz.build
index 94a30873ba..2ba1c6679a 100644
--- a/intl/locale/moz.build
+++ b/intl/locale/moz.build
@@ -35,7 +35,12 @@ EXPORTS += [
'nsWin32Locale.h',
]
+EXPORTS.mozilla.intl += [
+ 'LocaleService.h'
+]
+
UNIFIED_SOURCES += [
+ 'LocaleService.cpp',
'nsCollation.cpp',
'nsIDateTimeFormat.cpp',
'nsLanguageAtomService.cpp',