messages.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. (function () {
  2. // add your module to this map so it gets used
  3. var map = {
  4. 'fr': 'Français',
  5. 'es': 'Español',
  6. 'pl': 'Polski',
  7. 'de': 'Deutsch',
  8. 'pt-br': 'Português do Brasil',
  9. 'ro': 'Română',
  10. 'zh': '繁體中文',
  11. 'el': 'Ελληνικά',
  12. };
  13. var messages = {};
  14. var LS_LANG = "CRYPTPAD_LANG";
  15. var getStoredLanguage = function () { return localStorage && localStorage.getItem(LS_LANG); };
  16. var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage || ''; };
  17. var getLanguage = messages._getLanguage = function () {
  18. if (window.cryptpadLanguage) { return window.cryptpadLanguage; }
  19. if (getStoredLanguage()) { return getStoredLanguage(); }
  20. var l = getBrowserLanguage();
  21. // Edge returns 'fr-FR' --> transform it to 'fr' and check again
  22. return map[l] ? l :
  23. (map[l.split('-')[0]] ? l.split('-')[0] : 'en');
  24. };
  25. var language = getLanguage();
  26. // Translations files were migrated from requirejs modules to json.
  27. // To avoid asking every administrator to update their customized translation files,
  28. // we use a requirejs map to redirect the old path to the new one and to use the
  29. // requirejs json plugin
  30. var reqPaths = {
  31. "/common/translations/messages.js":"json!/common/translations/messages.json"
  32. };
  33. Object.keys(map).forEach(function (k) {
  34. reqPaths["/common/translations/messages."+k+".js"] = "json!/common/translations/messages."+k+".json";
  35. });
  36. require.config({
  37. map: {
  38. "*": reqPaths
  39. }
  40. });
  41. var req = ['/common/common-util.js', '/customize/translations/messages.js'];
  42. if (language && map[language]) { req.push('/customize/translations/messages.' + language + '.js'); }
  43. define(req, function(Util, Default, Language) {
  44. map.en = 'English';
  45. var defaultLanguage = 'en';
  46. Util.extend(messages, Default);
  47. if (Language && language !== defaultLanguage) {
  48. // Add the translated keys to the returned object
  49. Util.extend(messages, Language);
  50. }
  51. messages._languages = map;
  52. messages._languageUsed = language;
  53. messages._checkTranslationState = function (cb) {
  54. if (typeof(cb) !== "function") { return; }
  55. var allMissing = [];
  56. var reqs = [];
  57. Object.keys(map).forEach(function (code) {
  58. if (code === defaultLanguage) { return; }
  59. reqs.push('/customize/translations/messages.' + code + '.js');
  60. });
  61. require(reqs, function () {
  62. var langs = arguments;
  63. Object.keys(map).forEach(function (code, i) {
  64. if (code === defaultLanguage) { return; }
  65. var translation = langs[i];
  66. var missing = [];
  67. var checkInObject = function (ref, translated, path) {
  68. var updated = {};
  69. Object.keys(ref).forEach(function (k) {
  70. if (/^updated_[0-9]+_/.test(k) && !translated[k]) {
  71. var key = k.split('_').slice(2).join('_');
  72. // Make sure we don't already have an update for that key. It should not happen
  73. // but if it does, keep the latest version
  74. if (updated[key]) {
  75. var ek = updated[key];
  76. if (parseInt(ek.split('_')[1]) > parseInt(k.split('_')[1])) { return; }
  77. }
  78. updated[key] = k;
  79. }
  80. });
  81. Object.keys(ref).forEach(function (k) {
  82. if (/^_/.test(k) || k === 'driveReadme') { return; }
  83. var nPath = path.slice();
  84. nPath.push(k);
  85. if (!translated[k] || updated[k]) {
  86. if (updated[k]) {
  87. var uPath = path.slice();
  88. uPath.unshift('out');
  89. missing.push([code, nPath, 2, uPath.join('.') + '.' + updated[k]]);
  90. return;
  91. }
  92. return void missing.push([code, nPath, 1]);
  93. }
  94. if (typeof ref[k] !== typeof translated[k]) {
  95. return void missing.push([code, nPath, 3]);
  96. }
  97. if (typeof ref[k] === "object" && !Array.isArray(ref[k])) {
  98. checkInObject(ref[k], translated[k], nPath);
  99. }
  100. });
  101. Object.keys(translated).forEach(function (k) {
  102. if (/^_/.test(k) || k === 'driveReadme') { return; }
  103. var nPath = path.slice();
  104. nPath.push(k);
  105. if (typeof ref[k] === "undefined") {
  106. missing.push([code, nPath, 0]);
  107. }
  108. });
  109. };
  110. checkInObject(Default, translation, []);
  111. // Push the removals at the end
  112. missing.sort(function (a, b) {
  113. if (a[2] === 0 && b[2] !== 0) { return 1; }
  114. if (a[2] !== 0 && b[2] === 0) { return -1; }
  115. return 0;
  116. });
  117. Array.prototype.push.apply(allMissing, missing); // Destructive concat
  118. });
  119. cb(allMissing);
  120. });
  121. };
  122. // Get keys with parameters
  123. messages._getKey = function (key, argArray) {
  124. if (!messages[key]) { return '?'; }
  125. var text = messages[key];
  126. if (typeof(text) === 'string') {
  127. return text.replace(/\{(\d+)\}/g, function (str, p1) {
  128. if (typeof(argArray[p1]) === 'string' || typeof(argArray[p1]) === "number") {
  129. return argArray[p1];
  130. }
  131. console.error("Only strings and numbers can be used in _getKey params!");
  132. return '';
  133. });
  134. } else {
  135. return text;
  136. }
  137. };
  138. messages.driveReadme = '["BODY",{"class":"cke_editable cke_editable_themed cke_contents_ltr cke_show_borders","contenteditable":"true","spellcheck":"false","style":"color: rgb(51, 51, 51);"},' +
  139. '[["H1",{},["'+messages.readme_welcome+'"]],["P",{},["'+messages.readme_p1+'"]],["P",{},["'+messages.readme_p2+'"]],["HR",{},[]],["H2",{},["'+messages.readme_cat1+'",["BR",{},[]]]],["UL",{},[["LI",{},["'+messages._getKey("readme_cat1_l1", ['",["STRONG",{},["'+messages.newButton+'"]],"', '",["STRONG",{},["'+messages.type.pad+'"]],"'])+'"]],["LI",{},["'+messages.readme_cat1_l2+'"]],["LI",{},["'+messages._getKey("readme_cat1_l3", ['",["STRONG",{},["'+messages.fm_unsortedName+'"]],"'])+'",["UL",{},[["LI",{},["'+messages._getKey("readme_cat1_l3_l1", ['",["STRONG",{},["'+messages.fm_rootName+'"]],"'])+'"]],["LI",{},["'+messages.readme_cat1_l3_l2+'"]]]]]],["LI",{},["'+messages._getKey("readme_cat1_l4", ['",["STRONG",{},["'+messages.fm_trashName+'"]],"'])+'",["BR",{},[]]]]]],["P",{},[["BR",{},[]]]],["H2",{},["'+messages.readme_cat2+'",["BR",{},[]]]],["UL",{},[["LI",{},["'+messages._getKey("readme_cat2_l1", ['",["STRONG",{},["'+messages.shareButton+'"]],"', '",["STRONG",{},["'+messages.edit+'"]],"', '",["STRONG",{},["'+messages.view+'"]],"'])+'"]],["LI",{},["'+messages.readme_cat2_l2+'"]]]],["P",{},[["BR",{},[]]]],["H2",{},["'+messages.readme_cat3+'"]],["UL",{},[["LI",{},["'+messages.readme_cat3_l1+'"]],["LI",{},["'+messages.readme_cat3_l2+'"]],["LI",{},["'+messages.readme_cat3_l3+'",["BR",{},[]]]]]]],' +
  140. '{"metadata":{"defaultTitle":"' + messages.driveReadmeTitle + '","title":"' + messages.driveReadmeTitle + '"}}]';
  141. return messages;
  142. });
  143. }());