As regards the issue of languages you don’t support… I have this code which I found which somehow knows to use the en-US folder if the locale of the machine in use is not present.
The unload function is included because it’s used in the getString function.
Run getString.init in your start up function and getString(name); to get the actual value.
function getString(name) {
// Use the cached bundle to retrieve the string
var str;
try {
str = getString.bundle.GetStringFromName(name);
}
// Use the fallback in-case the string isn’t localized
catch(ex) {
console.log(name);
//str = getString.fallback.GetStringFromName(name);
}
return str;
}
/**
- Initialize getString() for the provided add-on.
-
-
@usage getString.init(addon): Load properties file for the add-on.
-
@param [object] addon: Add-on object from AddonManager
-
-
@usage getString.init(addon, getAlternate): Load properties with alternate.
-
@param [object] addon: Add-on object from AddonManager
-
@param [function] getAlternate: Convert a locale to an alternate locale
*/
getString.init = function(addon, getAlternate) {
// Set a default get alternate function if it doesn’t exist
if (typeof getAlternate != “function”)
getAlternate = function() “en-US”;
// Get the bundled properties file for the app’s locale
function getBundle(locale) {
let propertyPath = "locale/" + locale + "/singledomain.properties";
let propertyFile = addon.getResourceURI(propertyPath);
// Get a bundle and test if it's able to do simple things
try {
var bundle = Services.strings.createBundle(propertyFile.spec);
bundle.getSimpleEnumeration();
return bundle;
}
catch(ex) {}
// The locale must not exist, so give nothing
return null;
}
// Use the current locale or the alternate as the primary bundle
let locale = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIXULChromeRegistry).getSelectedLocale(“global”);
getString.bundle = getBundle(locale) || getBundle(getAlternate(locale));
// Create a fallback in-case a string is missing
getString.fallback = getBundle(“en-US”);
// Clear out the strings cache when cleaning up so new ones load
unload(function() Services.strings.flushBundles());
}
/**
- Save callbacks to run when unloading. Optionally scope the callback to a
- container, e.g., window. Provide a way to run all the callbacks.
-
-
@usage unload(): Run all callbacks and release them.
-
-
@usage unload(callback): Add a callback to run on unload.
-
@param [function] callback: 0-parameter function to call on unload.
-
@return [function]: A 0-parameter function that undoes adding the callback.
-
-
@usage unload(callback, container) Add a scoped callback to run on unload.
-
@param [function] callback: 0-parameter function to call on unload.
-
@param [node] container: Remove the callback when this container unloads.
-
@return [function]: A 0-parameter function that undoes adding the callback.
*/
function unload(callback, container) {
// Initialize the array of unloaders on the first usage
let unloaders = unload.unloaders;
if (unloaders == null)
unloaders = unload.unloaders = [];
// Calling with no arguments runs all the unloader callbacks
if (callback == null) {
unloaders.slice().forEach(function(unloader) unloader());
unloaders.length = 0;
return true;
}
// The callback is bound to the lifetime of the container if we have one
if (container != null) {
// Remove the unloader when the container unloads
container.addEventListener(“unload”, removeUnloader, false);
// Wrap the callback to additionally remove the unload listener
let origCallback = callback;
callback = function() {
container.removeEventListener("unload", removeUnloader, false);
origCallback();
}
}
// Wrap the callback in a function that ignores failures
function unloader() {
try {
callback();
}
catch(ex) {}
}
unloaders.push(unloader);
// Provide a way to remove the unloader
function removeUnloader() {
let index = unloaders.indexOf(unloader);
if (index != -1)
unloaders.splice(index, 1);
return true;
}
return removeUnloader;
}