Problems with Fluent when loading resources with Autoconfig Startup Scripting (userChrome.js)

This is a slightly weird issue as it happens when using Autoconfig Startup Scripting / userChrome.js. I know this is unsupported, but I would appreciate help, as it is the only way how to implement my project without completely forking Firefox.

I’m the developer of the PWAsForFirefox project, which is a tool to use Progressive Web Apps / Site-Specific Browsers in Firefox. Because normal WebExtensions have limitations that prevent such features from being implemented, a significant part of the tool are custom patches/scripts that are loaded into Firefox with the help of Autoconfig Startup Scripting. You can read a few more details on my documentation website. This part of the project is relevant to this topic.

One of the things I am currently working on is adding support for localization/translations for the UI of my Firefox modifications. In short, to implement this, I register Fluent localization sources for each supported language into Firefox’s L10nRegistry in the chrome/pwa/boot.jsm file (this is the file that is executed by userChrome.js at startup). Then, on each page where they are needed, specific Fluent files are loaded with document.l10n.addResourceIds.

This is a snippet that registers the Fluent sources at startup:

Services.obs.addObserver(async () => {
  const l10nLocales =  await LangPackMatcher.getAvailableLocales();
  if (!l10nLocales.includes('en-US')) l10nLocales.push('en-US');
  const l10nSource = new L10nFileSource('pwa', 'app', l10nLocales, 'resource://pwa/localization/{locale}/');
}, 'final-ui-startup');

In the current version, the resources are loaded for all languages that already have a language pack installed, as this simplifies some of the handling. This will likely be changed in the future, but it does not seem to be the main cause of my issue. The resource://pwa/ URI is registered to the correct path during the startup by some other userChrome.js scripts before the sources are registered to Fluent. The Fluent registration seems to work, no errors are reported, and localization partially works (see below for some examples). The full code is available here, and there is also a minimal reproducible example for my issue linked below.

The problem is that when my own resources and normal Firefox resources are loaded at the same time to the same Localization/DOMLocalization instance, the localization system breaks and returns only English messages, regardless of what the chosen locale is. Interestingly, when only my resources (or only Firefox resources) are loaded, they seem to work fine.

I tried a bunch of things (changed how filesources are registered, registered each language in a separate filesource, created a new Localization instance, etc.), but I couldn’t fix the problem. However, I think I found where this problem might happen, I just don’t know why it happens and how to fix it.

Based on my testing, the problem seems to be that when Fluent bundles are generated by the L10nRegistry.generateBundles function, and the bundles need to contain both built-in Firefox resources and my custom resources (registered with the code above), only the en-US bundles are returned for some reason, so all translations (both for built-in messages and my custom messages) are in English. I think that bundles are generated this Firefox function, but I don’t know what exactly causes this problem.

I prepared a minimal reproducible example in a separate repository that is available here. The repository contains example localization files and the code that should register then, and also provides steps to reproduce this issue and examples for additional testing.

You can see the original GitHub issue with my comments here.

Is there some issue with how I load/register my custom localization resources, or is this a bug with Firefox? And how to fix it? Thanks for your help!