i18n.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. 'use strict';
  2. var vsprintf = require('sprintf-js').vsprintf;
  3. function i18n(options){
  4. /* jshint validthis: true */
  5. options = options || {};
  6. this.data = {};
  7. this.languages = options.languages || ['default'];
  8. if (!Array.isArray(this.languages)){
  9. this.languages = [this.languages];
  10. }
  11. }
  12. i18n.prototype.get = function(languages){
  13. var data = this.data;
  14. var result = {};
  15. var lang, langData, keys, key, i, leni, j, lenj;
  16. if (languages){
  17. if (!Array.isArray(languages)){
  18. languages = [languages];
  19. }
  20. } else {
  21. languages = this.languages;
  22. }
  23. for (i = 0, leni = languages.length; i < leni; i++){
  24. lang = languages[i];
  25. langData = data[lang];
  26. if (!langData) continue;
  27. keys = Object.keys(langData);
  28. for (j = 0, lenj = keys.length; j < lenj; j++){
  29. key = keys[j];
  30. if (!result.hasOwnProperty(key)) result[key] = langData[key];
  31. }
  32. }
  33. return result;
  34. };
  35. i18n.prototype.set = function(lang, data){
  36. if (typeof lang !== 'string') throw new TypeError('lang must be a string!');
  37. if (typeof data !== 'object') throw new TypeError('data is required!');
  38. this.data[lang] = flattenObject(data);
  39. return this;
  40. };
  41. i18n.prototype.remove = function(lang){
  42. if (typeof lang !== 'string') throw new TypeError('lang must be a string!');
  43. delete this.data[lang];
  44. return this;
  45. };
  46. i18n.prototype.list = function(){
  47. return Object.keys(this.data);
  48. };
  49. function flattenObject(data, obj, parent){
  50. obj = obj || {};
  51. parent = parent || '';
  52. var keys = Object.keys(data);
  53. var key = '';
  54. var item;
  55. for (var i = 0, len = keys.length; i < len; i++){
  56. key = keys[i];
  57. item = data[key];
  58. if (typeof item === 'object'){
  59. flattenObject(item, obj, parent + key + '.');
  60. } else {
  61. obj[parent + key] = item;
  62. }
  63. }
  64. return obj;
  65. }
  66. i18n.prototype.__ = function(lang){
  67. var data = this.get(lang);
  68. return function(){
  69. var len = arguments.length;
  70. if (!len) return '';
  71. var args = new Array(len);
  72. for (var i = 0; i < len; i++){
  73. args[i] = arguments[i];
  74. }
  75. var key = args.shift();
  76. var str = data[key] || key;
  77. return vsprintf(str, args);
  78. };
  79. };
  80. i18n.prototype._p = function(lang){
  81. var data = this.get(lang);
  82. return function(){
  83. var len = arguments.length;
  84. if (!len) return '';
  85. var args = new Array(len);
  86. for (var i = 0; i < len; i++){
  87. args[i] = arguments[i];
  88. }
  89. var key = args.shift();
  90. var number = args.length ? +args[0] : 0;
  91. var str = key;
  92. if (!number && data.hasOwnProperty(key + '.zero')){
  93. str = data[key + '.zero'];
  94. } else if (number === 1 && data.hasOwnProperty(key + '.one')){
  95. str = data[key + '.one'];
  96. } else if (data.hasOwnProperty(key + '.other')){
  97. str = data[key + '.other'];
  98. } else if (data.hasOwnProperty(key)){
  99. str = data[key];
  100. }
  101. return vsprintf(str, args);
  102. };
  103. };
  104. module.exports = i18n;