UNPKG

@nextcloud/l10n

Version:

Nextcloud localization and translation helpers for apps and libraries

1 lines 6.44 kB
{"version":3,"file":"gettext.mjs","sources":["../lib/gettext.ts"],"sourcesContent":["/*!\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\n/**\n * This module provides functionality to translate applications independent from Nextcloud\n *\n * @packageDocumentation\n * @module @nextcloud/l10n/gettext\n * @example\n * ```js\nimport { getGettextBuilder } from '@nextcloud/l10n/gettext'\nconst gt = getGettextBuilder()\n\t\t\t.detectLocale() // or use setLanguage()\n\t\t\t.addTranslation(/* ... *\\/)\n\t\t\t.build()\ngt.gettext('some string to translate')\n```\n */\n\nimport type { AppTranslations, PluralFunction } from './registry.ts'\n\nimport { getLanguage, getPlural, translate, translatePlural } from './index.ts'\n\nexport interface GettextTranslation {\n\tmsgid: string\n\tmsgid_plural?: string\n\tmsgstr: string[]\n}\n\nexport interface GettextTranslationContext {\n\t[msgid: string]: GettextTranslation\n}\n\nexport interface GettextTranslationBundle {\n\theaders: {\n\t\t[headerName: string]: string\n\t}\n\ttranslations: {\n\t\t[context: string]: GettextTranslationContext\n\t}\n}\n\nclass GettextWrapper {\n\tprivate bundle: AppTranslations\n\n\tconstructor(pluralFunction: PluralFunction) {\n\t\tthis.bundle = {\n\t\t\tpluralFunction,\n\t\t\ttranslations: {},\n\t\t}\n\t}\n\n\t/**\n\t * Append new translations to the wrapper.\n\t *\n\t * This is useful if translations should be added on demand,\n\t * e.g. depending on component usage.\n\t *\n\t * @param bundle - The new translation bundle to append\n\t */\n\taddTranslations(bundle: GettextTranslationBundle): void {\n\t\tconst dict = Object.values(bundle.translations[''] ?? {})\n\t\t\t.map(({ msgid, msgid_plural: msgidPlural, msgstr }) => {\n\t\t\t\tif (msgidPlural !== undefined) {\n\t\t\t\t\treturn [`_${msgid}_::_${msgidPlural}_`, msgstr]\n\t\t\t\t}\n\t\t\t\treturn [msgid, msgstr[0]]\n\t\t\t})\n\n\t\tthis.bundle.translations = {\n\t\t\t...this.bundle.translations,\n\t\t\t...Object.fromEntries(dict),\n\t\t}\n\t}\n\n\t/**\n\t * Get translated string (singular form), optionally with placeholders\n\t *\n\t * @param original original string to translate\n\t * @param placeholders map of placeholder key to value\n\t */\n\tgettext(original: string, placeholders: Record<string, string | number> = {}): string {\n\t\treturn translate('', original, placeholders, undefined, { bundle: this.bundle })\n\t}\n\n\t/**\n\t * Get translated string with plural forms\n\t *\n\t * @param singular Singular text form\n\t * @param plural Plural text form to be used if `count` requires it\n\t * @param count The number to insert into the text\n\t * @param placeholders optional map of placeholder key to value\n\t */\n\tngettext(singular: string, plural: string, count: number, placeholders: Record<string, string | number> = {}): string {\n\t\treturn translatePlural('', singular, plural, count, placeholders, { bundle: this.bundle })\n\t}\n}\n\nclass GettextBuilder {\n\tprivate debug = false\n\tprivate language = 'en'\n\tprivate translations = {} as Record<string, GettextTranslationBundle>\n\n\tsetLanguage(language: string): this {\n\t\tthis.language = language\n\t\treturn this\n\t}\n\n\t/**\n\t * Try to detect locale from context with `en` as fallback value\n\t * This only works within a Nextcloud page context.\n\t *\n\t * @deprecated use `detectLanguage` instead.\n\t */\n\tdetectLocale(): this {\n\t\treturn this.detectLanguage()\n\t}\n\n\t/**\n\t * Try to detect locale from context with `en` as fallback value.\n\t * This only works within a Nextcloud page context.\n\t */\n\tdetectLanguage(): this {\n\t\treturn this.setLanguage(getLanguage().replace('-', '_'))\n\t}\n\n\t/**\n\t * Register a new translation bundle for a specified language.\n\t *\n\t * Please note that existing translations for that language will be overwritten.\n\t *\n\t * @param language - Language this is the translation for\n\t * @param data - The translation bundle\n\t */\n\taddTranslation(language: string, data: GettextTranslationBundle): this {\n\t\tthis.translations[language] = data\n\t\treturn this\n\t}\n\n\tenableDebugMode(): this {\n\t\tthis.debug = true\n\t\treturn this\n\t}\n\n\tbuild(): GettextWrapper {\n\t\tif (this.debug) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.debug(`Creating gettext instance for language ${this.language}`)\n\t\t}\n\n\t\tconst wrapper = new GettextWrapper((n: number) => getPlural(n, this.language))\n\t\tif (this.language in this.translations) {\n\t\t\twrapper.addTranslations(this.translations[this.language])\n\t\t}\n\t\treturn wrapper\n\t}\n}\n\n/**\n * Create a new GettextBuilder instance\n */\nexport function getGettextBuilder() {\n\treturn new GettextBuilder()\n}\n\nexport type {\n\tGettextBuilder,\n\tGettextWrapper,\n}\n"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;AA4CA,MAAM,eAAe;AAAA,EACZ;AAAA,EAER,YAAY,gBAAgC;AAC3C,SAAK,SAAS;AAAA,MACb;AAAA,MACA,cAAc,CAAA;AAAA,IAAC;AAAA,EAEjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,gBAAgB,QAAwC;AACvD,UAAM,OAAO,OAAO,OAAO,OAAO,aAAa,EAAE,KAAK,CAAA,CAAE,EACtD,IAAI,CAAC,EAAE,OAAO,cAAc,aAAa,aAAa;AACtD,UAAI,gBAAgB,QAAW;AAC9B,eAAO,CAAC,IAAI,KAAK,OAAO,WAAW,KAAK,MAAM;AAAA,MAC/C;AACA,aAAO,CAAC,OAAO,OAAO,CAAC,CAAC;AAAA,IACzB,CAAC;AAEF,SAAK,OAAO,eAAe;AAAA,MAC1B,GAAG,KAAK,OAAO;AAAA,MACf,GAAG,OAAO,YAAY,IAAI;AAAA,IAAA;AAAA,EAE5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,UAAkB,eAAgD,IAAY;AACrF,WAAO,UAAU,IAAI,UAAU,cAAc,QAAW,EAAE,QAAQ,KAAK,QAAQ;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,SAAS,UAAkB,QAAgB,OAAe,eAAgD,CAAA,GAAY;AACrH,WAAO,gBAAgB,IAAI,UAAU,QAAQ,OAAO,cAAc,EAAE,QAAQ,KAAK,QAAQ;AAAA,EAC1F;AACD;AAEA,MAAM,eAAe;AAAA,EACZ,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,eAAe,CAAA;AAAA,EAEvB,YAAY,UAAwB;AACnC,SAAK,WAAW;AAChB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAqB;AACpB,WAAO,KAAK,eAAA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAuB;AACtB,WAAO,KAAK,YAAY,YAAA,EAAc,QAAQ,KAAK,GAAG,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,eAAe,UAAkB,MAAsC;AACtE,SAAK,aAAa,QAAQ,IAAI;AAC9B,WAAO;AAAA,EACR;AAAA,EAEA,kBAAwB;AACvB,SAAK,QAAQ;AACb,WAAO;AAAA,EACR;AAAA,EAEA,QAAwB;AACvB,QAAI,KAAK,OAAO;AAEf,cAAQ,MAAM,0CAA0C,KAAK,QAAQ,EAAE;AAAA,IACxE;AAEA,UAAM,UAAU,IAAI,eAAe,CAAC,MAAc,UAAU,GAAG,KAAK,QAAQ,CAAC;AAC7E,QAAI,KAAK,YAAY,KAAK,cAAc;AACvC,cAAQ,gBAAgB,KAAK,aAAa,KAAK,QAAQ,CAAC;AAAA,IACzD;AACA,WAAO;AAAA,EACR;AACD;AAKO,SAAS,oBAAoB;AACnC,SAAO,IAAI,eAAA;AACZ;"}