phrasebook.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. const translation = require("./translation.js").translation;
  2. /**
  3. * This class repesents phrasebook, which is something like dictionary,
  4. * but not for words, for all phrases in app. It give functions which
  5. * could find and translates phrases.
  6. */
  7. class phrasebook {
  8. /**
  9. * @var {Map}
  10. * This store phrases in flat notation.
  11. */
  12. #phrases;
  13. /**
  14. * @var {?object}
  15. * This store object for nested object notation.
  16. */
  17. #objects;
  18. /**
  19. * This create new phrasebook from phrases map, and optional object
  20. * for phrases in object notation.
  21. *
  22. * @param {Map} phrases - This contain phrases in flat notation.
  23. * @param {?object} objects - This contain phrases in object notation.
  24. */
  25. constructor(phrases, objects = null) {
  26. if (!(phrases instanceof Map)) {
  27. throw new TypeError("Phrases must an map.");
  28. }
  29. if (objects !== null && typeof(objects) !== "object") {
  30. throw new TypeError("Objects must be null or object.");
  31. }
  32. this.#phrases = phrases;
  33. this.#objects = objects;
  34. }
  35. /**
  36. * This translate given phrase. When phrase is in the nested object
  37. * notation, then try to find phrase in objects. When not, try to find
  38. * phrase in the flat phrases. When could not find phrase, then return
  39. * not translated phrase. Content always is returned as translation
  40. * object, which could be also formated wich numbers, dates and
  41. * much more.
  42. *
  43. * @param {string} phrase - Phrase to translate.
  44. * @returns {translation} - Translated phrase.
  45. */
  46. translate(phrase) {
  47. if (typeof(phrase) !== "string") {
  48. throw new TypeError("Phrase to translate must be an string.");
  49. }
  50. if (this.#is_nested(phrase)) {
  51. return this.#translate_nested(phrase);
  52. }
  53. return this.#translate_flat(phrase);
  54. }
  55. /**
  56. * This translate given phrase. When phrase is in the nested object
  57. * notation, then try to find phrase in objects. When not, try to find
  58. * phrase in the flat phrases. When could not find phrase, then return
  59. * not translated phrase. Content always is returned as translation
  60. * object, which could be also formated wich numbers, dates and
  61. * much more.
  62. *
  63. * @param {string} phrase - Phrase to translate.
  64. * @returns {translation} - Translated phrase.
  65. */
  66. get(phrase) {
  67. return this.translate(phrase);
  68. }
  69. /**
  70. * Check that phrase is nested or not.
  71. *
  72. * @param {string} phrase - Phrase to check that is nested
  73. * @returns {bool} - True when nested, false when not
  74. */
  75. #is_nested(phrase) {
  76. return phrase.indexOf(".") !== -1;
  77. }
  78. /**
  79. * This translate object notated phrase.
  80. *
  81. * @param {string} phrase - Phrase to translate.
  82. * @returns {translation} - Translated phrase.
  83. */
  84. #translate_nested(phrase) {
  85. if (this.#objects === null) {
  86. return this.#translate_flat(phrase);
  87. }
  88. const parts = phrase.trim().split(".");
  89. let current = this.#objects;
  90. for (const count in parts) {
  91. const part = parts[count];
  92. if (!(part in current)) {
  93. return new translation(phrase, false);
  94. }
  95. current = current[part];
  96. }
  97. if (typeof(current) !== "string") {
  98. return new translation(phrase, false);
  99. }
  100. return new translation(current, true);
  101. }
  102. /**
  103. * This translate flat phrase.
  104. *
  105. * @param {string} phrase - Phrase to translate.
  106. * @returns {translation} - Translated phrase.
  107. */
  108. #translate_flat(phrase) {
  109. const prepared = phrasebook.prepare(phrase);
  110. const found = this.#phrases.has(prepared);
  111. const translated = found ? this.#phrases.get(prepared) : phrase;
  112. return new translation(translated, found);
  113. }
  114. /**
  115. * This prepars phrase, that mean replece all spaces with "_", trim
  116. * and also replace all big letters with lowwer.
  117. *
  118. * @param {string} content - Phrase to preapre.
  119. * @return {string} - Prepared phrase.
  120. */
  121. static prepare(content) {
  122. if (typeof(content) !== "string") {
  123. throw new TypeError("Content to prepare must be an string.");
  124. }
  125. return content
  126. .trim()
  127. .replaceAll(" ", "_")
  128. .replaceAll(".", "_")
  129. .toLowerCase();
  130. }
  131. }
  132. exports.phrasebook = phrasebook;