source/i18n.js in i18n-js-0.1.6 vs source/i18n.js in i18n-js-1.0.0

- old
+ new

@@ -12,343 +12,378 @@ // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`. I18n.PLACEHOLDER = /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm; I18n.lookup = function(scope, options) { - var translations = this.prepareOptions(I18n.translations); - var messages = translations[I18n.currentLocale()]; - options = this.prepareOptions(options); + var translations = this.prepareOptions(I18n.translations); + var messages = translations[I18n.currentLocale()]; + options = this.prepareOptions(options); - if (!messages) { - return; - } + if (!messages) { + return; + } - if (typeof(scope) == "object") { - scope = scope.join(this.defaultSeparator); - } + if (typeof(scope) == "object") { + scope = scope.join(this.defaultSeparator); + } - if (options.scope) { - scope = options.scope.toString() + this.defaultSeparator + scope; - } + if (options.scope) { + scope = options.scope.toString() + this.defaultSeparator + scope; + } - scope = scope.split(this.defaultSeparator); + scope = scope.split(this.defaultSeparator); - while (scope.length > 0) { - var currentScope = scope.shift(); - messages = messages[currentScope]; + while (scope.length > 0) { + var currentScope = scope.shift(); + messages = messages[currentScope]; - if (!messages) { - break; - } - } + if (!messages) { + break; + } + } - if (!messages && options.defaultValue != null && options.defaultValue != undefined) { - messages = options.defaultValue; - } + if (!messages && options.defaultValue != null && options.defaultValue != undefined) { + messages = options.defaultValue; + } - return messages; + return messages; }; // Merge serveral 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({name: "John Doe"}, {name: "Mary Doe", role: "user"}); +// #=> {name: "John Doe", role: "user"} // I18n.prepareOptions = function() { - var options = {}; - var opts; - var count = arguments.length; + var options = {}; + var opts; + var count = arguments.length; - for (var i = 0; i < count; i++) { - opts = arguments[i]; + for (var i = 0; i < count; i++) { + opts = arguments[i]; - if (!opts) { - continue; - } + if (!opts) { + continue; + } - for (var key in opts) { - if (options[key] == undefined || options[key] == null) { - options[key] = opts[key]; - } - } - } + for (var key in opts) { + if (options[key] == undefined || options[key] == null) { + options[key] = opts[key]; + } + } + } - return options; + return options; }; I18n.interpolate = function(message, options) { - options = this.prepareOptions(options); - var matches = message.match(this.PLACEHOLDER); + options = this.prepareOptions(options); + var matches = message.match(this.PLACEHOLDER); - if (!matches) { - return message; - } + if (!matches) { + return message; + } - var placeholder, value, name; + var placeholder, value, name; - for (var i = 0; placeholder = matches[i]; i++) { - name = placeholder.replace(this.PLACEHOLDER, "$1"); + for (var i = 0; placeholder = matches[i]; i++) { + name = placeholder.replace(this.PLACEHOLDER, "$1"); - value = options[name]; + value = options[name]; - if (options[name] == null || options[name] == undefined) { - value = "[missing " + placeholder + " value]"; - } + if (options[name] == null || options[name] == undefined) { + value = "[missing " + placeholder + " value]"; + } - regex = new RegExp(placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}")); - message = message.replace(regex, value); - } + regex = new RegExp(placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}")); + message = message.replace(regex, value); + } - return message; + return message; }; I18n.translate = function(scope, options) { - options = this.prepareOptions(options); - var translation = this.lookup(scope, options); + options = this.prepareOptions(options); + var translation = this.lookup(scope, options); - try { - if (typeof(translation) == "object") { - if (typeof(options.count) == "number") { - return this.pluralize(options.count, scope, options); - } else { - return translation; - } - } else { - return this.interpolate(translation, options); - } - } catch(err) { - return this.missingTranslation(scope); - } + try { + if (typeof(translation) == "object") { + if (typeof(options.count) == "number") { + return this.pluralize(options.count, scope, options); + } else { + return translation; + } + } else { + return this.interpolate(translation, options); + } + } catch(err) { + return this.missingTranslation(scope); + } }; I18n.localize = function(scope, value) { - switch (scope) { - case "currency": - return this.toCurrency(value); - case "number": - scope = this.lookup("number.format"); - return this.toNumber(value, scope); - case "percentage": - return this.toPercentage(value); - default: - if (scope.match(/^(date|time)/)) { - return this.toTime(scope, value); - } else { - return value.toString(); - } - } + switch (scope) { + case "currency": + return this.toCurrency(value); + case "number": + scope = this.lookup("number.format"); + return this.toNumber(value, scope); + case "percentage": + return this.toPercentage(value); + default: + if (scope.match(/^(date|time)/)) { + return this.toTime(scope, value); + } else { + return value.toString(); + } + } }; I18n.parseDate = function(d) { - var matches, date; - matches = d.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ |T](\d{2}):(\d{2}):(\d{2}))?(Z)?/); - - if (matches) { - // date/time strings: yyyy-mm-dd hh:mm:ss or yyyy-mm-dd or yyyy-mm-ddThh:mm:ssZ - for (var i = 1; i <= 6; i++) { - matches[i] = parseInt(matches[i], 10) || 0; - } + var matches, date; + matches = d.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ |T](\d{2}):(\d{2}):(\d{2}))?(Z)?/); + + if (matches) { + // date/time strings: yyyy-mm-dd hh:mm:ss or yyyy-mm-dd or yyyy-mm-ddThh:mm:ssZ + for (var i = 1; i <= 6; i++) { + matches[i] = parseInt(matches[i], 10) || 0; + } - // month starts on 0 - matches[2] -= 1; + // month starts on 0 + matches[2] -= 1; - if (matches[7]) { - date = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6])); - } else { - date = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]); - } - } else if (typeof(d) == "number") { - // UNIX timestamp - date = new Date(); - date.setTime(d); - } else { - // an arbitrary javascript string - date = new Date(); - date.setTime(Date.parse(d)); - } + if (matches[7]) { + date = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6])); + } else { + date = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]); + } + } else if (typeof(d) == "number") { + // UNIX timestamp + date = new Date(); + date.setTime(d); + } else { + // an arbitrary javascript string + date = new Date(); + date.setTime(Date.parse(d)); + } - return date; + return date; }; I18n.toTime = function(scope, d) { - var date = this.parseDate(d); - var format = this.lookup(scope); + var date = this.parseDate(d); + var format = this.lookup(scope); - if (date.toString().match(/invalid/i)) { - return date.toString(); - } + if (date.toString().match(/invalid/i)) { + return date.toString(); + } - if (!format) { - return date.toString(); - } + if (!format) { + return date.toString(); + } - return this.strftime(date, format); + return this.strftime(date, format); }; I18n.strftime = function(date, format) { - var options = this.lookup("date"); + var options = this.lookup("date"); - if (!options) { - return date.toString(); - } + if (!options) { + return date.toString(); + } - var weekDay = date.getDay(); - var day = date.getDate(); - var year = date.getFullYear(); - var month = date.getMonth() + 1; - var hour = date.getHours(); - var hour12 = hour; - var meridian = hour > 12? "PM" : "AM"; - var secs = date.getSeconds(); - var mins = date.getMinutes(); - var offset = date.getTimezoneOffset(); - var absOffsetHours = Math.floor(Math.abs(offset / 60)); - var absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60); - var timezoneoffset = (offset > 0 ? "-" : "+") + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes); + var weekDay = date.getDay(); + var day = date.getDate(); + var year = date.getFullYear(); + var month = date.getMonth() + 1; + var hour = date.getHours(); + var hour12 = hour; + var meridian = hour > 12? "PM" : "AM"; + var secs = date.getSeconds(); + var mins = date.getMinutes(); + var offset = date.getTimezoneOffset(); + var absOffsetHours = Math.floor(Math.abs(offset / 60)); + var absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60); + var timezoneoffset = (offset > 0 ? "-" : "+") + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes); - if (hour12 > 12) { - hour12 = hour12 - 12; - } + if (hour12 > 12) { + hour12 = hour12 - 12; + } - var padding = function(n) { - var s = "0" + n.toString(); - return s.substr(s.length - 2); - }; + var padding = function(n) { + var s = "0" + n.toString(); + return s.substr(s.length - 2); + }; - var f = format; - f = f.replace("%a", options["abbr_day_names"][weekDay]); - f = f.replace("%A", options["day_names"][weekDay]); - f = f.replace("%b", options["abbr_month_names"][month]); - f = f.replace("%B", options["month_names"][month]); - f = f.replace("%d", padding(day)); - f = f.replace("%-d", day); - f = f.replace("%H", padding(hour)); - f = f.replace("%-H", hour); - f = f.replace("%I", padding(hour12)); - f = f.replace("%-I", hour12); - f = f.replace("%m", padding(month)); - f = f.replace("%-m", month); - f = f.replace("%M", padding(mins)); - f = f.replace("%-M", mins); - f = f.replace("%p", meridian); - f = f.replace("%S", padding(secs)); - f = f.replace("%-S", secs); - f = f.replace("%w", weekDay); - f = f.replace("%y", padding(year)); - f = f.replace("%-y", padding(year).replace(/^0+/, "")); - f = f.replace("%Y", year); - f = f.replace("%z", timezoneoffset); + var f = format; + f = f.replace("%a", options["abbr_day_names"][weekDay]); + f = f.replace("%A", options["day_names"][weekDay]); + f = f.replace("%b", options["abbr_month_names"][month]); + f = f.replace("%B", options["month_names"][month]); + f = f.replace("%d", padding(day)); + f = f.replace("%-d", day); + f = f.replace("%H", padding(hour)); + f = f.replace("%-H", hour); + f = f.replace("%I", padding(hour12)); + f = f.replace("%-I", hour12); + f = f.replace("%m", padding(month)); + f = f.replace("%-m", month); + f = f.replace("%M", padding(mins)); + f = f.replace("%-M", mins); + f = f.replace("%p", meridian); + f = f.replace("%S", padding(secs)); + f = f.replace("%-S", secs); + f = f.replace("%w", weekDay); + f = f.replace("%y", padding(year)); + f = f.replace("%-y", padding(year).replace(/^0+/, "")); + f = f.replace("%Y", year); + f = f.replace("%z", timezoneoffset); - return f; + return f; }; I18n.toNumber = function(number, options) { - options = this.prepareOptions( - options, - this.lookup("number.format"), - {precision: 3, separator: ".", delimiter: ","} - ); - - var negative = number < 0; - var string = Math.abs(number).toFixed(options["precision"]).toString(); - var parts = string.split("."); + options = this.prepareOptions( + options, + this.lookup("number.format"), + {precision: 3, separator: ".", delimiter: ","} + ); + + var negative = number < 0; + var string = Math.abs(number).toFixed(options["precision"]).toString(); + var parts = string.split("."); - number = parts[0]; - var precision = parts[1]; + number = parts[0]; + var precision = parts[1]; - var n = []; + var n = []; - while (number.length > 0) { - n.unshift(number.substr(Math.max(0, number.length - 3), 3)); - number = number.substr(0, number.length -3); - } + while (number.length > 0) { + n.unshift(number.substr(Math.max(0, number.length - 3), 3)); + number = number.substr(0, number.length -3); + } - var formattedNumber = n.join(options["delimiter"]); + var formattedNumber = n.join(options["delimiter"]); - if (options["precision"] > 0) { - formattedNumber += options["separator"] + parts[1]; - } - - if (negative) { - formattedNumber = "-" + formattedNumber; - } + if (options["precision"] > 0) { + formattedNumber += options["separator"] + parts[1]; + } + + if (negative) { + formattedNumber = "-" + formattedNumber; + } - return formattedNumber; + return formattedNumber; }; I18n.toCurrency = function(number, options) { - options = this.prepareOptions( - options, - this.lookup("number.currency.format"), - this.lookup("number.format"), - {unit: "$", precision: 2, format: "%u%n", delimiter: ",", separator: "."} - ); + options = this.prepareOptions( + options, + this.lookup("number.currency.format"), + this.lookup("number.format"), + {unit: "$", precision: 2, format: "%u%n", delimiter: ",", separator: "."} + ); - number = this.toNumber(number, options); - number = options["format"] - .replace("%u", options["unit"]) - .replace("%n", number); + number = this.toNumber(number, options); + number = options["format"] + .replace("%u", options["unit"]) + .replace("%n", number); - return number; + return number; }; +I18n.toHumanSize = function(number, options) { + var kb = 1024 + , size = number + , iterations = 0 + , unit + , precision; + + while (size >= kb && iterations < 4) { + size = size / kb; + iterations += 1; + }; + + switch (iterations) { + case 0: + unit = this.t("number.human.storage_units.units.byte", {count: size}); + precision = 0; + break; + default: + 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: "%n%u", delimiter: ""} + ); + + number = this.toNumber(size, options); + number = options["format"] + .replace("%u", unit) + .replace("%n", number); + + return number; +}; + I18n.toPercentage = function(number, options) { - options = this.prepareOptions( - options, - this.lookup("number.percentage.format"), - this.lookup("number.format"), - {precision: 3, separator: ".", delimiter: ""} - ); + options = this.prepareOptions( + options, + this.lookup("number.percentage.format"), + this.lookup("number.format"), + {precision: 3, separator: ".", delimiter: ""} + ); - number = this.toNumber(number, options); - return number + "%"; + number = this.toNumber(number, options); + return number + "%"; }; I18n.pluralize = function(count, scope, options) { - var translation; - - try { - translation = this.lookup(scope, options); - } catch (error) {} - - if (!translation) { - return this.missingTranslation(scope); - } - - var message; - options = this.prepareOptions(options); - options["count"] = count.toString(); + var translation; + + try { + translation = this.lookup(scope, options); + } catch (error) {} + + if (!translation) { + return this.missingTranslation(scope); + } + + var message; + options = this.prepareOptions(options); + options["count"] = count.toString(); - switch(Math.abs(count)) { - case 0: - message = translation["zero"] || translation["none"] || translation["other"] || this.missingTranslation(scope, "zero"); - break; - case 1: - message = translation["one"] || this.missingTranslation(scope, "one"); - break; - default: - message = translation["other"] || this.missingTranslation(scope, "other"); - } + switch(Math.abs(count)) { + case 0: + message = translation["zero"] || translation["none"] || translation["other"] || this.missingTranslation(scope, "zero"); + break; + case 1: + message = translation["one"] || this.missingTranslation(scope, "one"); + break; + default: + message = translation["other"] || this.missingTranslation(scope, "other"); + } - return this.interpolate(message, options); + return this.interpolate(message, options); }; I18n.missingTranslation = function() { - var message = '[missing "' + this.currentLocale(); - var count = arguments.length; + var message = '[missing "' + this.currentLocale(); + var count = arguments.length; - for (var i = 0; i < count; i++) { - message += "." + arguments[i]; - } + for (var i = 0; i < count; i++) { + message += "." + arguments[i]; + } - message += '" translation]'; + message += '" translation]'; - return message; + return message; }; I18n.currentLocale = function() { - return (I18n.locale || I18n.defaultLocale); + return (I18n.locale || I18n.defaultLocale); }; // shortcuts I18n.t = I18n.translate; I18n.l = I18n.localize;