diff --git a/js/misc/extensionUtils.js b/js/misc/extensionUtils.js index a8133d8a2..c86468e4b 100644 --- a/js/misc/extensionUtils.js +++ b/js/misc/extensionUtils.js @@ -1,7 +1,8 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- /* exported ExtensionState, ExtensionType, getCurrentExtension, - getSettings, initTranslations, openPrefs, isOutOfDate, - installImporter, serializeExtension, deserializeExtension */ + getSettings, initTranslations, gettext, ngettext, pgettext, + openPrefs, isOutOfDate, installImporter, serializeExtension, + deserializeExtension */ // Common utils for the extension system and the extension // preferences tool @@ -112,6 +113,64 @@ function initTranslations(domain) { Gettext.bindtextdomain(domain, localeDir.get_path()); else Gettext.bindtextdomain(domain, Config.LOCALEDIR); + + Object.assign(extension, Gettext.domain(domain)); +} + +/** + * gettext: + * @param {string} str - the string to translate + * + * Translate @str using the extension's gettext domain + * + * @returns {string} - the translated string + * + */ +function gettext(str) { + return callExtensionGettextFunc('gettext', str); +} + +/** + * ngettext: + * @param {string} str - the string to translate + * @param {string} strPlural - the plural form of the string + * @param {number} n - the quantity for which translation is needed + * + * Translate @str and choose plural form using the extension's + * gettext domain + * + * @returns {string} - the translated string + * + */ +function ngettext(str, strPlural, n) { + return callExtensionGettextFunc('ngettext', str, strPlural, n); +} + +/** + * pgettext: + * @param {string} context - context to disambiguate @str + * @param {string} str - the string to translate + * + * Translate @str in the context of @context using the extension's + * gettext domain + * + * @returns {string} - the translated string + * + */ +function pgettext(context, str) { + return callExtensionGettextFunc('pgettext', context, str); +} + +function callExtensionGettextFunc(func, ...args) { + const extension = getCurrentExtension(); + + if (!extension) + throw new Error(`${func}() can only be called from extensions`); + + if (!extension[func]) + throw new Error(`${func}() is used without calling initTranslations() first`); + + return extension[func](...args); } /** diff --git a/lint/eslintrc-shell.yml b/lint/eslintrc-shell.yml index bb0636f02..42a829a63 100644 --- a/lint/eslintrc-shell.yml +++ b/lint/eslintrc-shell.yml @@ -18,6 +18,7 @@ overrides: - files: js/** excludedFiles: - js/portalHelper/* + - js/misc/extensionUtils.js globals: global: readonly _: readonly diff --git a/subprojects/extensions-tool/src/templates/indicator/extension.js b/subprojects/extensions-tool/src/templates/indicator/extension.js index 5d9753efc..9ed2c385c 100644 --- a/subprojects/extensions-tool/src/templates/indicator/extension.js +++ b/subprojects/extensions-tool/src/templates/indicator/extension.js @@ -22,14 +22,13 @@ const GETTEXT_DOMAIN = 'my-indicator-extension'; const { GObject, St } = imports.gi; -const Gettext = imports.gettext.domain(GETTEXT_DOMAIN); -const _ = Gettext.gettext; - const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; +const _ = ExtensionUtils.gettext; + const Indicator = GObject.registerClass( class Indicator extends PanelMenu.Button { _init() {