Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "nsLanguageAtomService.h"
7 : #include "nsUConvPropertySearch.h"
8 : #include "nsUnicharUtils.h"
9 : #include "nsIAtom.h"
10 : #include "mozilla/ArrayUtils.h"
11 : #include "mozilla/ClearOnShutdown.h"
12 : #include "mozilla/Encoding.h"
13 : #include "mozilla/intl/OSPreferences.h"
14 : #include "mozilla/ServoBindings.h"
15 :
16 : using namespace mozilla;
17 : using mozilla::intl::OSPreferences;
18 :
19 : static constexpr nsUConvProp encodingsGroups[] = {
20 : #include "encodingsgroups.properties.h"
21 : };
22 :
23 : static constexpr nsUConvProp kLangGroups[] = {
24 : #include "langGroups.properties.h"
25 : };
26 :
27 : // static
28 : nsLanguageAtomService*
29 39 : nsLanguageAtomService::GetService()
30 : {
31 39 : static UniquePtr<nsLanguageAtomService> gLangAtomService;
32 39 : if (!gLangAtomService) {
33 3 : gLangAtomService = MakeUnique<nsLanguageAtomService>();
34 3 : ClearOnShutdown(&gLangAtomService);
35 : }
36 39 : return gLangAtomService.get();
37 : }
38 :
39 : nsIAtom*
40 4 : nsLanguageAtomService::LookupLanguage(const nsACString &aLanguage)
41 : {
42 8 : nsAutoCString lowered(aLanguage);
43 4 : ToLowerCase(lowered);
44 :
45 8 : nsCOMPtr<nsIAtom> lang = NS_Atomize(lowered);
46 8 : return GetLanguageGroup(lang);
47 : }
48 :
49 : already_AddRefed<nsIAtom>
50 30 : nsLanguageAtomService::LookupCharSet(NotNull<const Encoding*> aEncoding)
51 : {
52 60 : nsAutoCString charset;
53 30 : aEncoding->Name(charset);
54 60 : nsAutoCString group;
55 30 : if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
56 : encodingsGroups, ArrayLength(encodingsGroups), charset, group))) {
57 28 : return RefPtr<nsIAtom>(nsGkAtoms::Unicode).forget();
58 : }
59 2 : return NS_Atomize(group);
60 : }
61 :
62 : nsIAtom*
63 33 : nsLanguageAtomService::GetLocaleLanguage()
64 : {
65 : do {
66 33 : if (!mLocaleLanguage) {
67 4 : nsAutoCString locale;
68 2 : OSPreferences::GetInstance()->GetSystemLocale(locale);
69 :
70 2 : ToLowerCase(locale); // use lowercase for all language atoms
71 2 : mLocaleLanguage = NS_Atomize(locale);
72 : }
73 : } while (0);
74 :
75 33 : return mLocaleLanguage;
76 : }
77 :
78 : nsIAtom*
79 129 : nsLanguageAtomService::GetLanguageGroup(nsIAtom *aLanguage, bool* aNeedsToCache)
80 : {
81 129 : nsIAtom *retVal = mLangToGroup.GetWeak(aLanguage);
82 :
83 129 : if (!retVal) {
84 5 : if (aNeedsToCache) {
85 0 : *aNeedsToCache = true;
86 0 : return nullptr;
87 : }
88 10 : nsCOMPtr<nsIAtom> uncached = GetUncachedLanguageGroup(aLanguage);
89 5 : retVal = uncached.get();
90 :
91 5 : AssertIsMainThreadOrServoLangFontPrefsCacheLocked();
92 : // The hashtable will keep an owning reference to the atom
93 5 : mLangToGroup.Put(aLanguage, uncached);
94 : }
95 :
96 129 : return retVal;
97 : }
98 :
99 : already_AddRefed<nsIAtom>
100 5 : nsLanguageAtomService::GetUncachedLanguageGroup(nsIAtom* aLanguage) const
101 : {
102 10 : nsAutoCString langStr;
103 5 : aLanguage->ToUTF8String(langStr);
104 :
105 10 : nsAutoCString langGroupStr;
106 : nsresult res =
107 5 : nsUConvPropertySearch::SearchPropertyValue(kLangGroups,
108 5 : ArrayLength(kLangGroups),
109 5 : langStr, langGroupStr);
110 11 : while (NS_FAILED(res)) {
111 3 : int32_t hyphen = langStr.RFindChar('-');
112 3 : if (hyphen <= 0) {
113 0 : langGroupStr.AssignLiteral("x-unicode");
114 0 : break;
115 : }
116 3 : langStr.Truncate(hyphen);
117 3 : res = nsUConvPropertySearch::SearchPropertyValue(kLangGroups,
118 3 : ArrayLength(kLangGroups),
119 3 : langStr, langGroupStr);
120 : }
121 :
122 10 : nsCOMPtr<nsIAtom> langGroup = NS_Atomize(langGroupStr);
123 :
124 10 : return langGroup.forget();
125 : }
|