From dc0d4911b000e9bab7d1e05cfb8d6895a0722894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Thu, 26 Dec 2024 17:19:08 +0000 Subject: [PATCH] refactor(web): migrate src/agama to TypeScript --- web/src/agama.js | 99 -------------------------------------------- web/src/agama.ts | 99 ++++++++++++++++++++++++++++++++++++++++++++ web/src/i18n.test.ts | 14 +++---- 3 files changed, 106 insertions(+), 106 deletions(-) delete mode 100644 web/src/agama.js create mode 100644 web/src/agama.ts diff --git a/web/src/agama.js b/web/src/agama.js deleted file mode 100644 index e89e0ded3f..0000000000 --- a/web/src/agama.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) [2024] SUSE LLC - * - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, contact SUSE LLC. - * - * To contact SUSE LLC about this file by physical or electronic mail, you may - * find current contact information at www.suse.com. - */ - -/** - * This module provides a global "agama" object which can be use from other - * scripts like "po.js". - */ - -const agama = { - // the current language - language: "en", -}; - -// mapping with the current translations -let translations = {}; -// function used for computing the plural form index -let plural_fn; - -// set the current translations, called from po..js -agama.locale = function locale(po) { - if (po) { - Object.assign(translations, po); - - const header = po[""]; - if (header) { - if (header["plural-forms"]) plural_fn = header["plural-forms"]; - if (header.language) agama.language = header.language; - } - } else if (po === null) { - translations = {}; - plural_fn = undefined; - agama.language = "en"; - } -}; - -/** - * get a translation for a singular text - * @param {string} str input text - * @return translated text or the original text if the translation is not found - */ -agama.gettext = function gettext(str) { - if (translations) { - const translated = translations[str]; - if (translated?.[0]) return translated[0]; - } - - // fallback, return the original text - return str; -}; - -/** - * get a translation for a plural text - * @param {string} str1 input singular text - * @param {string} strN input plural text - * @param {number} n the actual number which decides whether to use the - * singular or plural form (of which plural form if there are several of them) - * @return translated text or the original text if the translation is not found - */ -agama.ngettext = function ngettext(str1, strN, n) { - if (translations && plural_fn) { - // plural form translations are indexed by the singular variant - const translation = translations[str1]; - - if (translation) { - const plural_index = plural_fn(n); - - // the plural function either returns direct index (integer) in the plural - // translations or a boolean indicating simple plural form which - // needs to be converted to index 0 (singular) or 1 (plural) - const index = plural_index === true ? 1 : plural_index || 0; - - if (translation[index]) return translation[index]; - } - } - - // fallback, return the original text - return n === 1 ? str1 : strN; -}; - -export default agama; diff --git a/web/src/agama.ts b/web/src/agama.ts new file mode 100644 index 0000000000..9ecc8a57cf --- /dev/null +++ b/web/src/agama.ts @@ -0,0 +1,99 @@ +/* + * Copyright (c) [2024] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +/** + * This module provides a global "agama" object which can be use from other + * scripts like "po.js". + */ + +// mapping with the current translations +let translations = {}; +// function used for computing the plural form index +let plural_fn: (n: number) => boolean; + +const agama = { + // the current language + language: "en", + + // set the current translations, called from po..js + locale: (po) => { + if (po) { + Object.assign(translations, po); + + const header = po[""]; + if (header) { + if (header["plural-forms"]) plural_fn = header["plural-forms"]; + if (header.language) agama.language = header.language; + } + } else if (po === null) { + translations = {}; + plural_fn = undefined; + agama.language = "en"; + } + }, + + /** + * Get a translation for a singular text + * @param str input text + * @return translated text or the original text if the translation is not found + */ + gettext: (str: string): string => { + if (translations) { + const translated = translations[str]; + if (translated?.[0]) return translated[0]; + } + + // fallback, return the original text + return str; + }, + + /** + * get a translation for a plural text + * @param str1 input singular text + * @param strN input plural text + * @param n the actual number which decides whether to use the + * singular or plural form (of which plural form if there are several of them) + * @return translated text or the original text if the translation is not found + */ + ngettext: (str1: string, strN: string, n: number) => { + if (translations && plural_fn) { + // plural form translations are indexed by the singular variant + const translation = translations[str1]; + + if (translation) { + const plural_index = plural_fn(n); + + // the plural function either returns direct index (integer) in the plural + // translations or a boolean indicating simple plural form which + // needs to be converted to index 0 (singular) or 1 (plural) + const index = plural_index === true ? 1 : plural_index || 0; + + if (translation[index]) return translation[index]; + } + } + + // fallback, return the original text + return n === 1 ? str1 : strN; + }, +}; + +export default agama; diff --git a/web/src/i18n.test.ts b/web/src/i18n.test.ts index 6c620a30b1..e05f6c3522 100644 --- a/web/src/i18n.test.ts +++ b/web/src/i18n.test.ts @@ -24,11 +24,11 @@ import { _, n_, N_, Nn_ } from "~/i18n"; import agama from "~/agama"; // mock the cockpit gettext functions -jest.mock("~/agama"); -const gettextFn = jest.fn(); -agama.gettext.mockImplementation(gettextFn); -const ngettextFn = jest.fn(); -agama.ngettext.mockImplementation(ngettextFn); +jest.mock("~/agama", () => ({ + ...jest.requireActual("~/agama"), + gettext: jest.fn(), + ngettext: jest.fn(), +})); // some testing texts const text = "text to translate"; @@ -40,7 +40,7 @@ describe("i18n", () => { it("calls the agama.gettext() implementation", () => { _(text); - expect(gettextFn).toHaveBeenCalledWith(text); + expect(agama.gettext).toHaveBeenCalledWith(text); }); }); @@ -48,7 +48,7 @@ describe("i18n", () => { it("calls the agama.ngettext() implementation", () => { n_(singularText, pluralText, 1); - expect(ngettextFn).toHaveBeenCalledWith(singularText, pluralText, 1); + expect(agama.ngettext).toHaveBeenCalledWith(singularText, pluralText, 1); }); });