[gnome-shell] extensionUtils: Add gettext convenience helpers



commit 1deb13e1aaabfd04b2641976a224b6fc2be3b9ec
Author: Florian Müllner <fmuellner gnome org>
Date:   Sun Apr 12 02:45:55 2020 +0200

    extensionUtils: Add gettext convenience helpers
    
    We have initTranslations() for binding an extension's
    gettext domain, but nothing to help with using gettext
    from an extension.
    
    Such help would be useful though, as an extension that
    calls textdomain() like a normal application would
    inadvertently changes the default domain for the whole
    gnome-shell process.
    
    Instead, extensions have to use domain-specific versions
    of the gettext functions:
    
    ```js
    const Gettext = imports.gettext.domain('my-extension');
    const _ = Gettext.gettext;
    ```
    
    Make this a bit easier by adding those functions directly
    to the extensions object when initTranslations() is called,
    then expose helper functions for calling them.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2594
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1941>

 js/misc/extensionUtils.js                          | 63 +++++++++++++++++++++-
 lint/eslintrc-shell.yml                            |  1 +
 .../src/templates/indicator/extension.js           |  5 +-
 3 files changed, 64 insertions(+), 5 deletions(-)
---
diff --git a/js/misc/extensionUtils.js b/js/misc/extensionUtils.js
index a8133d8a2e..c86468e4b4 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 bb0636f021..42a829a63b 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 5d9753efc4..9ed2c385ca 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() {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]