mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-12 10:14:10 +01:00
153 lines
5.4 KiB
TypeScript
153 lines
5.4 KiB
TypeScript
import { I18nService as I18nServiceAbstraction } from '../abstractions/i18n.service';
|
|
|
|
export class I18nService implements I18nServiceAbstraction {
|
|
locale: string;
|
|
// First locale is the default (English)
|
|
supportedTranslationLocales: string[] = ['en'];
|
|
translationLocale: string;
|
|
collator: Intl.Collator;
|
|
localeNames = new Map<string, string>([
|
|
['af', 'Afrikaans'],
|
|
['be', 'Беларуская'],
|
|
['bg', 'български'],
|
|
['ca', 'català'],
|
|
['cs', 'čeština'],
|
|
['da', 'dansk'],
|
|
['de', 'Deutsch'],
|
|
['el', 'Ελληνικά'],
|
|
['en', 'English'],
|
|
['en-GB', 'English (British)'],
|
|
['eo', 'Esperanto'],
|
|
['es', 'español'],
|
|
['et', 'eesti'],
|
|
['fa', 'فارسی'],
|
|
['fi', 'suomi'],
|
|
['fr', 'français'],
|
|
['he', 'עברית'],
|
|
['hi', 'हिन्दी'],
|
|
['hr', 'hrvatski'],
|
|
['hu', 'magyar'],
|
|
['id', 'Bahasa Indonesia'],
|
|
['it', 'italiano'],
|
|
['ja', '日本語'],
|
|
['ko', '한국어'],
|
|
['lv', 'Latvietis'],
|
|
['ml', 'മലയാളം'],
|
|
['nb', 'norsk (bokmål)'],
|
|
['nl', 'Nederlands'],
|
|
['pl', 'polski'],
|
|
['pt-BR', 'português do Brasil'],
|
|
['pt-PT', 'português'],
|
|
['ro', 'română'],
|
|
['ru', 'русский'],
|
|
['sk', 'slovenčina'],
|
|
['sr', 'Српски'],
|
|
['sv', 'svenska'],
|
|
['th', 'ไทย'],
|
|
['tr', 'Türkçe'],
|
|
['uk', 'українська'],
|
|
['vi', 'Tiếng Việt'],
|
|
['zh-CN', '中文(中国大陆)'],
|
|
['zh-TW', '中文(台灣)'],
|
|
]);
|
|
|
|
protected inited: boolean;
|
|
protected defaultMessages: any = {};
|
|
protected localeMessages: any = {};
|
|
|
|
constructor(protected systemLanguage: string, protected localesDirectory: string,
|
|
protected getLocalesJson: (formattedLocale: string) => Promise<any>) {
|
|
this.systemLanguage = systemLanguage.replace('_', '-');
|
|
}
|
|
|
|
async init(locale?: string) {
|
|
if (this.inited) {
|
|
throw new Error('i18n already initialized.');
|
|
}
|
|
if (this.supportedTranslationLocales == null || this.supportedTranslationLocales.length === 0) {
|
|
throw new Error('supportedTranslationLocales not set.');
|
|
}
|
|
|
|
this.inited = true;
|
|
this.locale = this.translationLocale = locale != null ? locale : this.systemLanguage;
|
|
|
|
try {
|
|
this.collator = new Intl.Collator(this.locale, { numeric: true, sensitivity: 'base' });
|
|
} catch {
|
|
this.collator = null;
|
|
}
|
|
|
|
if (this.supportedTranslationLocales.indexOf(this.translationLocale) === -1) {
|
|
this.translationLocale = this.translationLocale.slice(0, 2);
|
|
|
|
if (this.supportedTranslationLocales.indexOf(this.translationLocale) === -1) {
|
|
this.translationLocale = this.supportedTranslationLocales[0];
|
|
}
|
|
}
|
|
|
|
if (this.localesDirectory != null) {
|
|
await this.loadMessages(this.translationLocale, this.localeMessages);
|
|
if (this.translationLocale !== this.supportedTranslationLocales[0]) {
|
|
await this.loadMessages(this.supportedTranslationLocales[0], this.defaultMessages);
|
|
}
|
|
}
|
|
}
|
|
|
|
t(id: string, p1?: string, p2?: string, p3?: string): string {
|
|
return this.translate(id, p1, p2, p3);
|
|
}
|
|
|
|
translate(id: string, p1?: string, p2?: string, p3?: string): string {
|
|
let result: string;
|
|
if (this.localeMessages.hasOwnProperty(id) && this.localeMessages[id]) {
|
|
result = this.localeMessages[id];
|
|
} else if (this.defaultMessages.hasOwnProperty(id) && this.defaultMessages[id]) {
|
|
result = this.defaultMessages[id];
|
|
} else {
|
|
result = '';
|
|
}
|
|
|
|
if (result !== '') {
|
|
if (p1 != null) {
|
|
result = result.split('__$1__').join(p1);
|
|
}
|
|
if (p2 != null) {
|
|
result = result.split('__$2__').join(p2);
|
|
}
|
|
if (p3 != null) {
|
|
result = result.split('__$3__').join(p3);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async loadMessages(locale: string, messagesObj: any): Promise<any> {
|
|
const formattedLocale = locale.replace('-', '_');
|
|
const locales = await this.getLocalesJson(formattedLocale);
|
|
for (const prop in locales) {
|
|
if (!locales.hasOwnProperty(prop)) {
|
|
continue;
|
|
}
|
|
messagesObj[prop] = locales[prop].message;
|
|
|
|
if (locales[prop].placeholders) {
|
|
for (const placeProp in locales[prop].placeholders) {
|
|
if (!locales[prop].placeholders.hasOwnProperty(placeProp) ||
|
|
!locales[prop].placeholders[placeProp].content) {
|
|
continue;
|
|
}
|
|
|
|
const replaceToken = '\\$' + placeProp.toUpperCase() + '\\$';
|
|
let replaceContent = locales[prop].placeholders[placeProp].content;
|
|
if (replaceContent === '$1' || replaceContent === '$2' || replaceContent === '$3') {
|
|
replaceContent = '__$' + replaceContent + '__';
|
|
}
|
|
messagesObj[prop] = messagesObj[prop].replace(new RegExp(replaceToken, 'g'), replaceContent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|