From 97be728b31204448fcf307e67a2ce7667ec5fe7b Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 11 Apr 2018 15:07:33 -0400 Subject: [PATCH] move base i18nservice out to jslib --- src/services/i18n.service.ts | 102 +++++++++++++++++++++++++++++++++++ src/services/index.ts | 1 + 2 files changed, 103 insertions(+) create mode 100644 src/services/i18n.service.ts diff --git a/src/services/i18n.service.ts b/src/services/i18n.service.ts new file mode 100644 index 0000000000..54d081c143 --- /dev/null +++ b/src/services/i18n.service.ts @@ -0,0 +1,102 @@ +import { I18nService as I18nServiceAbstraction } from '../abstractions/i18n.service'; + +export class I18nService implements I18nServiceAbstraction { + locale: string; + translationLocale: string; + collator: Intl.Collator; + + // First locale is the default (English) + protected supportedTranslationLocales: string[] = ['en']; + protected inited: boolean; + protected defaultMessages: any = {}; + protected localeMessages: any = {}; + + constructor(protected systemLanguage: string, protected localesDirectory: string) { } + + 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; + this.collator = new Intl.Collator(this.locale); + + 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.localesDirectory, this.translationLocale, this.localeMessages); + if (this.translationLocale !== this.supportedTranslationLocales[0]) { + await this.loadMessages(this.localesDirectory, 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(localesDir: string, locale: string, messagesObj: any): Promise { + const formattedLocale = locale.replace('-', '_'); + const file = await fetch(localesDir + formattedLocale + '/messages.json'); + const locales = await file.json(); + 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); + } + } + } + } + +} diff --git a/src/services/index.ts b/src/services/index.ts index 006e7deaeb..bddd1809b8 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -9,6 +9,7 @@ export { ContainerService } from './container.service'; export { CryptoService } from './crypto.service'; export { EnvironmentService } from './environment.service'; export { FolderService } from './folder.service'; +export { I18nService } from './i18n.service'; export { LockService } from './lock.service'; export { PasswordGenerationService } from './passwordGeneration.service'; export { SearchService } from './search.service';