-
-
Notifications
You must be signed in to change notification settings - Fork 210
/
module.web.js
106 lines (88 loc) 路 2.84 KB
/
module.web.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// @flow
import {
USES_FAHRENHEIT,
USES_IMPERIAL,
USES_RTL_LAYOUT,
CURRENCIES,
} from "./constants";
import type { Locale, LocalizationConstants } from "./types";
function getCountryCode(languageTagParts: string[]): ?string {
// overwrite Latin America and Caribbean region
return languageTagParts[1] === "419" ? "UN" : languageTagParts[1];
}
function getLocaleFromLanguageTag(
languageTag: string,
countryCodeFallback: string,
): Locale {
const splitted = languageTag.split("-");
const languageCode = splitted[0];
const countryCode = getCountryCode(splitted) || countryCodeFallback;
return {
languageCode: languageCode,
countryCode,
languageTag: `${languageCode}-${countryCode}`,
isRTL: USES_RTL_LAYOUT.includes(languageCode),
};
}
function getFirstCountryCode(languageTags: $ReadOnlyArray<string>): ?string {
for (let i = 0; i < languageTags.length; i++) {
const countryCode = getCountryCode(languageTags[i].split("-"));
if (countryCode) {
return countryCode;
}
}
}
function generateConstants(
languageTags: $ReadOnlyArray<string>,
): LocalizationConstants {
const countryCode = getFirstCountryCode(languageTags);
const locales: Locale[] = [];
const currencies: string[] = [];
languageTags.forEach(languageTag => {
const locale = getLocaleFromLanguageTag(languageTag, countryCode);
const currency = CURRENCIES[locale.countryCode];
if (!locales.find(_ => _.languageTag === locale.languageTag)) {
locales.push(locale);
}
if (currency && !currencies.includes(currency)) {
currencies.push(currency);
}
});
if (currencies.length === 0) {
currencies.push("USD");
}
const numberFormatter = new Intl.NumberFormat(locales[0].languageTag);
const dateFormatter = new Intl.DateTimeFormat(locales[0].languageTag, {
hour: "numeric",
});
const numberSeparators = [
...numberFormatter.format(1000000.1).replace(/\d/g, ""),
];
const numberFormatSettings = {
decimalSeparator: numberSeparators[numberSeparators.length - 1],
groupingSeparator: numberSeparators[0],
};
const eveningDate = new Date(2000, 0, 1, 20);
const uses24HourClock = !!dateFormatter.format(eveningDate).match(/am|pm/i);
return {
calendar: "gregorian",
country: countryCode,
currencies,
locales,
numberFormatSettings,
temperatureUnit: USES_FAHRENHEIT.includes(countryCode)
? "fahrenheit"
: "celsius",
timeZone: dateFormatter.resolvedOptions().timeZone || "Etc/UTC",
uses24HourClock,
usesMetricSystem: !USES_IMPERIAL.includes(countryCode),
};
}
export const handlers: Set<Function> = new Set();
export let constants: LocalizationConstants = generateConstants(
navigator.languages,
);
window.addEventListener("languagechange", () => {
constants = generateConstants(navigator.languages);
handlers.forEach(handler => handler());
});