diff options
Diffstat (limited to 'components/jetpack/sdk/l10n.js')
-rw-r--r-- | components/jetpack/sdk/l10n.js | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/components/jetpack/sdk/l10n.js b/components/jetpack/sdk/l10n.js new file mode 100644 index 000000000..db5a9d7b6 --- /dev/null +++ b/components/jetpack/sdk/l10n.js @@ -0,0 +1,91 @@ +/* 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"; + +module.metadata = { + "stability": "stable" +}; + +const json = require("./l10n/json/core"); +const { get: getKey } = require("./l10n/core"); +const properties = require("./l10n/properties/core"); +const { getRulesForLocale } = require("./l10n/plural-rules"); + +// Retrieve the plural mapping function +var pluralMappingFunction = getRulesForLocale(json.language()) || + getRulesForLocale("en"); + +exports.get = function get(k) { + // For now, we only accept a "string" as first argument + // TODO: handle plural forms in gettext pattern + if (typeof k !== "string") + throw new Error("First argument of localization method should be a string"); + let n = arguments[1]; + + // Get translation from big hashmap or default to hard coded string: + let localized = getKey(k, n) || k; + + // # Simplest usecase: + // // String hard coded in source code: + // _("Hello world") + // // Identifier of a key stored in properties file + // _("helloString") + if (arguments.length <= 1) + return localized; + + let args = Array.slice(arguments); + let placeholders = [null, ...args.slice(typeof(n) === "number" ? 2 : 1)]; + + if (typeof localized == "object" && "other" in localized) { + // # Plural form: + // // Strings hard coded in source code: + // _(["One download", "%d downloads"], 10); + // // Identifier of a key stored in properties file + // _("downloadNumber", 0); + let n = arguments[1]; + + // First handle simple universal forms that may not be mandatory + // for each language, (i.e. not different than 'other' form, + // but still usefull for better phrasing) + // For example 0 in english is the same form than 'other' + // but we accept 'zero' form if specified in localization file + if (n === 0 && "zero" in localized) + localized = localized["zero"]; + else if (n === 1 && "one" in localized) + localized = localized["one"]; + else if (n === 2 && "two" in localized) + localized = localized["two"]; + else { + let pluralForm = pluralMappingFunction(n); + if (pluralForm in localized) + localized = localized[pluralForm]; + else // Fallback in case of error: missing plural form + localized = localized["other"]; + } + + // Simulate a string with one placeholder: + args = [null, n]; + } + + // # String with placeholders: + // // Strings hard coded in source code: + // _("Hello %s", username) + // // Identifier of a key stored in properties file + // _("helloString", username) + // * We supports `%1s`, `%2s`, ... pattern in order to change arguments order + // in translation. + // * In case of plural form, we has `%d` instead of `%s`. + let offset = 1; + if (placeholders.length > 1) { + args = placeholders; + } + + localized = localized.replace(/%(\d*)[sd]/g, (v, n) => { + let rv = args[n != "" ? n : offset]; + offset++; + return rv; + }); + + return localized; +} |