Source code

Revision control

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* The downloaded Fluent file is located in this sub-directory of the local
* profile directory.
*/
const RS_DOWNLOADED_FILE_SUBDIR = "settings/main/ms-language-packs";
const USE_REMOTE_L10N_PREF =
"browser.newtabpage.activity-stream.asrouter.useRemoteL10n";
const { XPCOMUtils } = ChromeUtils.import(
);
XPCOMUtils.defineLazyModuleGetters(this, {
});
class _RemoteL10n {
constructor() {
this._l10n = null;
}
createElement(doc, elem, options = {}) {
let node;
if (options.content && options.content.string_id) {
node = doc.createElement("remote-text");
} else {
node = doc.createElementNS("http://www.w3.org/1999/xhtml", elem);
}
if (options.classList) {
node.classList.add(options.classList);
}
this.setString(node, options);
return node;
}
// If `string_id` is present it means we are relying on fluent for translations.
// Otherwise, we have a vanilla string.
setString(el, { content, attributes = {} }) {
if (content && content.string_id) {
for (let [fluentId, value] of Object.entries(attributes)) {
el.setAttribute(`fluent-variable-${fluentId}`, value);
}
el.setAttribute("fluent-remote-id", content.string_id);
} else {
el.textContent = content;
}
}
/**
* Creates a new DOMLocalization instance with the Fluent file from Remote Settings.
*
* Note: it will use the local Fluent file in any of following cases:
* * the remote Fluent file is not available
* * it was told to use the local Fluent file
*/
_createDOML10n() {
/* istanbul ignore next */
async function* generateBundles(resourceIds) {
const appLocale = Services.locale.appLocaleAsBCP47;
const appLocales = Services.locale.appLocalesAsBCP47;
const l10nFluentDir = OS.Path.join(
OS.Constants.Path.localProfileDir,
RS_DOWNLOADED_FILE_SUBDIR
);
const fs = new FileSource("cfr", [appLocale], `file://${l10nFluentDir}/`);
// In the case that the Fluent file has not been downloaded from Remote Settings,
// `fetchFile` will return `false` and fall back to the packaged Fluent file.
const resource = await fs.fetchFile(appLocale, "asrouter.ftl");
for await (let bundle of L10nRegistry.generateBundles(
appLocales.slice(0, 1),
resourceIds
)) {
// Override built-in messages with the resource loaded from remote settings for
// the app locale, i.e. the first item of `appLocales`.
if (resource) {
bundle.addResource(resource, { allowOverrides: true });
}
yield bundle;
}
// Now generating bundles for the rest of locales of `appLocales`.
yield* L10nRegistry.generateBundles(appLocales.slice(1), resourceIds);
}
return new DOMLocalization(
[
"browser/newtab/asrouter.ftl",
"browser/branding/brandings.ftl",
"browser/branding/sync-brand.ftl",
"branding/brand.ftl",
],
false,
Services.prefs.getBoolPref(USE_REMOTE_L10N_PREF, true)
? { generateBundles }
: {}
);
}
get l10n() {
if (!this._l10n) {
this._l10n = this._createDOML10n();
}
return this._l10n;
}
reloadL10n() {
this._l10n = null;
}
}
this.RemoteL10n = new _RemoteL10n();
const EXPORTED_SYMBOLS = ["RemoteL10n", "_RemoteL10n"];