Bug 1455649: Allow adding and removing resource Ids from a Localization. draft
authorDave Townsend <dtownsend@oxymoronical.com>
Fri, 27 Apr 2018 14:17:43 -0700
changeset 792231 d76dd026cce57fd55a7b29f41379414d670cb243
parent 792230 9af4fded9abda28d09129875a3422ca8cbac16a8
child 792232 803830d93b1c10b3169b20c93188f6d8ac8e3914
child 792819 5def6721a5ae0cdebdebc002d15c101807173dfa
child 794878 a781ca6ff20c1684465a2cef718e76b105292430
push id109051
push userdtownsend@mozilla.com
push dateMon, 07 May 2018 22:18:01 +0000
bugs1455649
milestone62.0a1
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
intl/l10n/Localization.jsm
intl/l10n/test/test_localization.js
--- 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);
+});