discourse/app/assets/javascripts/locales/i18n.js
Josh Soref 59097b207f
DEV: Correct typos and spelling mistakes (#12812)
Over the years we accrued many spelling mistakes in the code base. 

This PR attempts to fix spelling mistakes and typos in all areas of the code that are extremely safe to change 

- comments
- test descriptions
- other low risk areas
2021-05-21 11:43:47 +10:00

343 lines
8.6 KiB
JavaScript

// Instantiate the object
var I18n = I18n || {};
// Set default locale to english
I18n.defaultLocale = "en";
// Set default pluralization rule
I18n.pluralizationRules = {
en: function(n) {
return n === 0 ? ["zero", "none", "other"] : n === 1 ? "one" : "other";
}
};
// Set current locale to null
I18n.locale = null;
I18n.fallbackLocale = null;
// Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.
I18n.PLACEHOLDER = /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm;
I18n.SEPARATOR = ".";
I18n.noFallbacks = false;
I18n.isValidNode = function(obj, node, undefined) {
return obj[node] !== null && obj[node] !== undefined;
};
I18n.lookup = function(scope, options) {
options = options || {};
var translations = this.prepareOptions(I18n.translations),
locale = options.locale || I18n.currentLocale(),
messages = translations[locale] || {},
currentScope;
options = this.prepareOptions(options);
if (typeof scope === "object") {
scope = scope.join(this.SEPARATOR);
}
if (options.scope) {
scope = options.scope.toString() + this.SEPARATOR + scope;
}
var originalScope = scope;
scope = scope.split(this.SEPARATOR);
if (scope.length > 0 && scope[0] !== "js") {
scope.unshift("js");
}
while (messages && scope.length > 0) {
currentScope = scope.shift();
messages = messages[currentScope];
}
if (messages === undefined && this.extras && this.extras[locale]) {
messages = this.extras[locale];
scope = originalScope.split(this.SEPARATOR);
while (messages && scope.length > 0) {
currentScope = scope.shift();
messages = messages[currentScope];
}
}
if (messages === undefined) {
messages = options.defaultValue;
}
return messages;
};
// Merge several hash options, checking if value is set before
// overwriting any value. The precedence is from left to right.
//
// I18n.prepareOptions({name: "John Doe"}, {name: "Mary Doe", role: "user"});
// #=> {name: "John Doe", role: "user"}
//
I18n.prepareOptions = function() {
var options = {},
opts,
count = arguments.length;
for (var i = 0; i < count; i++) {
opts = arguments[i];
if (!opts) {
continue;
}
for (var key in opts) {
if (!this.isValidNode(options, key)) {
options[key] = opts[key];
}
}
}
return options;
};
I18n.interpolate = function(message, options) {
options = this.prepareOptions(options);
var matches = message.match(this.PLACEHOLDER),
placeholder,
value,
name;
if (!matches) {
return message;
}
for (var i = 0; (placeholder = matches[i]); i++) {
name = placeholder.replace(this.PLACEHOLDER, "$1");
if (typeof options[name] === "string") {
// The dollar sign (`$`) is a special replace pattern, and `$&` inserts
// the matched string. Thus dollars signs need to be escaped with the
// special pattern `$$`, which inserts a single `$`.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter
value = options[name].replace(/\$/g, "$$$$");
} else {
value = options[name];
}
if (!this.isValidNode(options, name)) {
value = "[missing " + placeholder + " value]";
}
var regex = new RegExp(
placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}")
);
message = message.replace(regex, value);
}
return message;
};
I18n.translate = function(scope, options) {
options = this.prepareOptions(options);
options.needsPluralization = typeof options.count === "number";
options.ignoreMissing = !this.noFallbacks;
var translation = this.findTranslation(scope, options);
if (!this.noFallbacks) {
if (!translation && this.fallbackLocale) {
options.locale = this.fallbackLocale;
translation = this.findTranslation(scope, options);
}
options.ignoreMissing = false;
if (!translation && this.currentLocale() !== this.defaultLocale) {
options.locale = this.defaultLocale;
translation = this.findTranslation(scope, options);
}
if (!translation && this.currentLocale() !== "en") {
options.locale = "en";
translation = this.findTranslation(scope, options);
}
}
try {
return this.interpolate(translation, options);
} catch (error) {
return this.missingTranslation(scope);
}
};
I18n.findTranslation = function(scope, options) {
var translation = this.lookup(scope, options);
if (translation && options.needsPluralization) {
translation = this.pluralize(translation, scope, options);
}
return translation;
};
I18n.toNumber = function(number, options) {
options = this.prepareOptions(options, this.lookup("number.format"), {
precision: 3,
separator: this.SEPARATOR,
delimiter: ",",
strip_insignificant_zeros: false
});
var negative = number < 0,
string = Math.abs(number)
.toFixed(options.precision)
.toString(),
parts = string.split(this.SEPARATOR),
buffer = [],
formattedNumber;
number = parts[0];
while (number.length > 0) {
buffer.unshift(number.substr(Math.max(0, number.length - 3), 3));
number = number.substr(0, number.length - 3);
}
formattedNumber = buffer.join(options.delimiter);
if (options.precision > 0) {
formattedNumber += options.separator + parts[1];
}
if (negative) {
formattedNumber = "-" + formattedNumber;
}
if (options.strip_insignificant_zeros) {
var regex = {
separator: new RegExp(options.separator.replace(/\./, "\\.") + "$"),
zeros: /0+$/
};
formattedNumber = formattedNumber
.replace(regex.zeros, "")
.replace(regex.separator, "");
}
return formattedNumber;
};
I18n.toHumanSize = function(number, options) {
var kb = 1024,
size = number,
iterations = 0,
unit,
precision;
while (size >= kb && iterations < 4) {
size = size / kb;
iterations += 1;
}
if (iterations === 0) {
unit = this.t("number.human.storage_units.units.byte", { count: size });
precision = 0;
} else {
unit = this.t(
"number.human.storage_units.units." +
[null, "kb", "mb", "gb", "tb"][iterations]
);
precision = size - Math.floor(size) === 0 ? 0 : 1;
}
options = this.prepareOptions(options, {
precision: precision,
format: this.t("number.human.storage_units.format"),
delimiter: ""
});
number = this.toNumber(size, options);
number = options.format.replace("%u", unit).replace("%n", number);
return number;
};
I18n.pluralizer = function(locale) {
var pluralizer = this.pluralizationRules[locale];
if (pluralizer !== undefined) return pluralizer;
return this.pluralizationRules["en"];
};
I18n.findAndTranslateValidNode = function(keys, translation) {
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (this.isValidNode(translation, key)) return translation[key];
}
return null;
};
I18n.pluralize = function(translation, scope, options) {
if (typeof translation !== "object") return translation;
options = this.prepareOptions(options);
var count = options.count.toString();
var pluralizer = this.pluralizer(options.locale || this.currentLocale());
var key = pluralizer(Math.abs(count));
var keys = typeof key === "object" && key instanceof Array ? key : [key];
var message = this.findAndTranslateValidNode(keys, translation);
if (message !== null || options.ignoreMissing) {
return message;
}
return this.missingTranslation(scope, keys[0]);
};
I18n.missingTranslation = function(scope, key) {
var message = "[" + this.currentLocale() + this.SEPARATOR + scope;
if (key) {
message += this.SEPARATOR + key;
}
return message + "]";
};
I18n.currentLocale = function() {
return I18n.locale || I18n.defaultLocale;
};
I18n.enableVerboseLocalization = function() {
var counter = 0;
var keys = {};
var t = I18n.t;
I18n.noFallbacks = true;
I18n.t = I18n.translate = function(scope, value) {
var current = keys[scope];
if (!current) {
current = keys[scope] = ++counter;
var message = "Translation #" + current + ": " + scope;
if (value && Object.keys(value).length > 0) {
message += ", parameters: " + JSON.stringify(value);
}
// eslint-disable-next-line no-console
console.info(message);
}
return t.apply(I18n, [scope, value]) + " (#" + current + ")";
};
};
I18n.enableVerboseLocalizationSession = function() {
sessionStorage.setItem("verbose_localization", "true");
I18n.enableVerboseLocalization();
return "Verbose localization is enabled. Close the browser tab to turn it off. Reload the page to see the translation keys.";
};
// shortcuts
I18n.t = I18n.translate;