Skip to content

Per-extension language preferences #258

@hanguokai

Description

@hanguokai

Update: In order to express it completely and clearly, I reorganized the proposal and edited it many times after 2022-09-12.

Summary

Currently, browser.i18n only display one default language to users. Users can't change the language to other extension supported languages independently. Developers need to use their own solutions to provide users with multiple language select menu.

It makes sense for an app to use another language independently of the operating system. For example, Android supports per-app language preferences (here is its docs and video). The same goes for extensions. This proposal brings per-app language preferences to browser extensions.

Tracking bugs: Chromium-1365283 , Firefox-1791356

Main Content

1. Browser built-in supply a language select menu per extension

Screen Shot 2022-09-04 at 14 30 17

Since this is a general purpose feature for all users and extensions, browser built-in support is best.

If browsers built-in support a language select menu per extensions, all developers, all existing extensions and users can get this benefit right away. Ideally, developers just use current i18n api without doing anything. Another benefit is that it's much easier for developers to test i18n.

2. New APIs for developers

/**
 * get the current language used by i18n.getMessage()
 * return the language tag,  e.g. en-US, zh-CN.
 */
i18n.getCurrentLanguage() => code: String.

/**
 * set a new language used in this extension.
 * if code is null, revert to the default state(follow the browser UI language).
 * if code is not valid, reject it.
 * return a Promise, resolved when the operation is complete.
 */
i18n.setCurrentLanguage(code: String) => Promise<void>

/**
 * get all languages that supported by this extensions.
 * return a Promise, resolved with an array of language tags.
 */
i18n.getAllLanguages() => code_array: Promise<Array<String>>

/**
 * After i18n changed to a new language, the browser triggers a language changed event.
 * callback is (new_language_code: String) => void
 */
i18n.onLanguageChanged.addListener(callback)

Ideally, developers just use current i18n api without doing anything if there is a browser-supplied language select menu. The new api is only used to integrate this feature with the developer-supplied language select menu. For example, in the extension's options page, developers use get/setCurrentLanguage and getAllLanguages to create a language select menu for users.

i18n.setCurrentLanguage(code) is persistent. It is a setting per extensions which saved by browsers. If the extension remove a language in the new version and current language is that, then browser fall back to the default language.

code is standard language code, like 'en-US', not 'en_US'(folder name).

How to get language display names? Use Intl.DisplayNames, for example:

const currentLanguage = i18n.getCurrentLanguage();
const displayName = new Intl.DisplayNames([currentLanguage], 
      { type: 'language' , languageDisplay: 'standard' });

const allLanguages = await i18n.getAllLanguages();
for (let code of allLanguages) {
    let name = displayName.of(code)); // language display name for code
    // use code and name to create a language select
}

After changing the language, the browser triggers a onLanguageChanged event. This event is useful for updating UI for already opened extension pages and other UI parts like badgeText, badgeTitle and context menu.

i18n.onLanguageChanged.addListener(function(newCode) {
    // update extension page
    button.textContent = i18n.getMessage(buttonLabel);

    // update extension UI parts
    action.setTitle({title: i18n.getMessage(title)});
    action.setBadgeText({text: i18n.getMessage(text)});
    contextMenus.update(...);
});

3. Another New API (optional for implementation)

i18n.getMessage(messageName, substitutions?,  {language: "langCode"})

At present, i18n.getMessage() doesn't allow specifying a different language. I suggest add a new property to specify a language in the options parameter(the 3rd parameter which already support a "escapeLt" property). Maybe it is useful for some developers or some use cases.

Related References

https://developer.chrome.com/docs/extensions/reference/i18n/
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n
https://crbug.com/660704
#252

Metadata

Metadata

Assignees

No one assigned

    Labels

    i18n-trackerGroup bringing to attention of Internationalization, or tracked by i18n but not needing response.proposalProposal for a change or new featuresupportive: chromeSupportive from Chromesupportive: firefoxSupportive from Firefoxsupportive: safariSupportive from Safaritopic: localization

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions