extensions: Replace exported gettext functions

Use the new defineTranslationFunctions() method from the previous
commit to create gettext functions for the module, instead of
re-exporting from the shared module.

It is now up to extension developers to use the more effective

```js
import {Extension} from 'etensions/extension.js';
const {gettext: _} =
    Extension.defineTranslationFunctions(import.meta.url);
```

or the more convenient

```js
import {Extension, gettext} from 'extensions/extension.js';
const _ = gettext;
```

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2838>
This commit is contained in:
Florian Müllner 2023-07-17 01:13:06 +02:00
parent f59d523694
commit 931ca5e4ab
3 changed files with 8 additions and 96 deletions

View File

@ -1,7 +1,5 @@
import {ExtensionBase, GettextWrapper, setExtensionManager} from './sharedInternals.js';
export {gettext, ngettext, pgettext} from './sharedInternals.js';
const {extensionManager} = imports.ui.main;
setExtensionManager(extensionManager);
@ -24,3 +22,7 @@ export class Extension extends ExtensionBase {
extensionManager.openExtensionPrefs(this.uuid, '', {});
}
}
export const {
gettext, ngettext, pgettext,
} = Extension.defineTranslationFunctions();

View File

@ -5,8 +5,6 @@ import {extensionManager} from '../extensionsService.js';
setExtensionManager(extensionManager);
export {gettext, ngettext, pgettext} from './sharedInternals.js';
export class ExtensionPreferences extends ExtensionBase {
static defineTranslationFunctions(url) {
const wrapper = new GettextWrapper(this, url);
@ -22,3 +20,7 @@ export class ExtensionPreferences extends ExtensionBase {
throw new GObject.NotImplementedError();
}
}
export const {
gettext, ngettext, pgettext,
} = ExtensionPreferences.defineTranslationFunctions();

View File

@ -276,95 +276,3 @@ export class GettextWrapper {
};
}
}
/**
* @private
*
* @returns {?object} - The current extension, or null if not called from
* an extension.
*/
function getCurrentExtension() {
const basePath = '/gnome-shell/extensions/';
// Search for an occurrence of an extension stack frame
// Start at 1 because 0 is the stack frame of this function
const [, ...stack] = new Error().stack.split('\n');
const extensionLine = stack.find(
line => line.includes(basePath));
if (!extensionLine)
return null;
// The exact stack line differs depending on where the function
// was called (function or module scope), and whether it's called
// from a module or legacy import (file:// URI vs. plain path).
//
// We don't have to care about the exact composition, all we need
// is a string that can be traversed as path and contains the UUID
let path = extensionLine.slice(extensionLine.indexOf(basePath));
// Walk up the directory tree, looking for an extension with
// the same UUID as a directory name.
do {
path = GLib.path_get_dirname(path);
const dirName = GLib.path_get_basename(path);
const extension = _extensionManager.lookup(dirName);
if (extension !== undefined)
return extension.stateObj;
} while (path !== '/');
return null;
}
/**
* Translate @str using the extension's gettext domain
*
* @param {string} str - the string to translate
*
* @returns {string} - the translated string
*/
export function gettext(str) {
return callExtensionGettextFunc('gettext', str);
}
/**
* Translate @str and choose plural form using the extension's
* gettext domain
*
* @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
*
* @returns {string} - the translated string
*/
export function ngettext(str, strPlural, n) {
return callExtensionGettextFunc('ngettext', str, strPlural, n);
}
/**
* Translate @str in the context of @context using the extension's
* gettext domain
*
* @param {string} context - context to disambiguate @str
* @param {string} str - the string to translate
*
* @returns {string} - the translated string
*/
export function pgettext(context, str) {
return callExtensionGettextFunc('pgettext', context, str);
}
/**
* @private
* @param {string} func - function name
* @param {*[]} args - function arguments
*/
function callExtensionGettextFunc(func, ...args) {
const extension = getCurrentExtension();
if (!extension)
throw new Error(`${func}() can only be called from extensions`);
return extension[func](...args);
}