Bug 1455649: Allow adding and removing resource Ids from a Localization.
This allows dynamically adding and removing resource Ids from a Localization
instance supporting updating the DOMLocalization when new link tags are
detected in a document.
MozReview-Commit-ID: 5qUnDYsNHBb
--- a/intl/l10n/Localization.jsm
+++ b/intl/l10n/Localization.jsm
@@ -124,16 +124,26 @@ class Localization {
* @returns {Localization}
*/
constructor(resourceIds, generateMessages = defaultGenerateMessages) {
this.resourceIds = resourceIds;
this.generateMessages = generateMessages;
this.ctxs = new CachedAsyncIterable(this.generateMessages(this.resourceIds));
}
+ addResourceIds(resourceIds) {
+ this.resourceIds.push(...resourceIds);
+ this.onLanguageChange();
+ }
+
+ removeResourceIds(resourceIds) {
+ this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r));
+ this.onLanguageChange();
+ }
+
/**
* Format translations and handle fallback if needed.
*
* Format translations for `keys` from `MessageContext` instances on this
* DOMLocalization. In case of errors, fetch the next context in the
* fallback chain.
*
* @param {Array<Object>} keys - Translation keys to format.
--- a/intl/l10n/test/test_localization.js
+++ b/intl/l10n/test/test_localization.js
@@ -38,16 +38,17 @@ add_task(async function test_methods_cal
], generateMessages);
let values = await l10n.formatValues([{id: "key"}, {id: "key2"}]);
equal(values[0], "[de] Value2");
equal(values[1], "[en] Value3");
L10nRegistry.sources.clear();
+ L10nRegistry.ctxCache.clear();
L10nRegistry.load = originalLoad;
Services.locale.setRequestedLocales(originalRequested);
});
add_task(async function test_builtins() {
const { L10nRegistry, FileSource } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm", {});
@@ -84,10 +85,60 @@ key = { PLATFORM() ->
], generateMessages);
let values = await l10n.formatValues([{id: "key"}]);
ok(values[0].includes(
`${ known_platforms[AppConstants.platform].toUpperCase() } Value`));
L10nRegistry.sources.clear();
+ L10nRegistry.ctxCache.clear();
L10nRegistry.load = originalLoad;
});
+
+add_task(async function test_add_remove_resourceIds() {
+ const { L10nRegistry, FileSource } =
+ ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm", {});
+
+ const fs = {
+ "/localization/en-US/browser/menu.ftl": "key1 = Value1",
+ "/localization/en-US/toolkit/menu.ftl": "key2 = Value2",
+ };
+ const originalLoad = L10nRegistry.load;
+ const originalRequested = Services.locale.getRequestedLocales();
+
+ L10nRegistry.load = async function(url) {
+ return fs[url];
+ };
+
+ const source = new FileSource("test", ["en-US"], "/localization/{locale}");
+ L10nRegistry.registerSource(source);
+
+ async function* generateMessages(resIds) {
+ yield * await L10nRegistry.generateContexts(["en-US"], resIds);
+ }
+
+ const l10n = new Localization(["/browser/menu.ftl"], generateMessages);
+
+ let values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ equal(values[0], "Value1");
+ equal(values[1], undefined);
+
+ l10n.addResourceIds(["/toolkit/menu.ftl"]);
+
+ values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ equal(values[0], "Value1");
+ equal(values[1], "Value2");
+
+ l10n.removeResourceIds(["/browser/menu.ftl"]);
+
+ values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ equal(values[0], undefined);
+ equal(values[1], "Value2");
+
+ L10nRegistry.sources.clear();
+ L10nRegistry.ctxCache.clear();
+ L10nRegistry.load = originalLoad;
+ Services.locale.setRequestedLocales(originalRequested);
+});