LocalizedStrings.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { LanguageService } from "./LanguageService";
  2. import { StringTypes } from "./StringTypes";
  3. type LangInfo = { [id: string]: string };
  4. type LangData = { [id: string]: LangInfo };
  5. type LangObject = { [id: string]: LangData };
  6. export class LocalizedStrings {
  7. private document: Document = document;
  8. constructor(
  9. private service: LanguageService,
  10. private i18nData: LangObject,
  11. private listenToChange = false
  12. ) {
  13. if (this.listenToChange) {
  14. service.registerLanguageChangeListener(() => {
  15. this.updateTagText();
  16. });
  17. }
  18. }
  19. getString(id: string, type: string): string {
  20. let i18nObj = this.i18nData[this.service.getLang()];
  21. if (!i18nObj) {
  22. console.warn(
  23. `Internal Error. The language set at ivprog.lang is not valid: ${this.service.getLang()}`
  24. );
  25. return this.getDefaultString(id, type);
  26. }
  27. if (!i18nObj[type]) {
  28. return this.getDefaultString(id, type);
  29. } else if (!i18nObj[type][id]) {
  30. return this.getDefaultString(id, type);
  31. } else {
  32. return i18nObj[type][id];
  33. }
  34. }
  35. private getDefaultString(id: string, type: string): string {
  36. let i18nObj = this.i18nData[this.service.getDefaultLang()];
  37. if (!i18nObj[type]) {
  38. return `{MISSING_I18N_TYPE_IDENTIFIER: ${type}}`;
  39. } else if (!i18nObj[type][id]) {
  40. return `{MISSING_I18N_IDENTIFIER: ${id}}`;
  41. } else {
  42. return i18nObj[type][id];
  43. }
  44. }
  45. getOR(): String {
  46. return this.getUI("string_join_or");
  47. }
  48. getError(id: string, context: [] = []) {
  49. const text = this.getString(id, StringTypes.ERROR);
  50. return this.processString(text, context);
  51. }
  52. getMessage(id: string, context: [] = []) {
  53. const text = this.getString(id, StringTypes.MESSAGE);
  54. return this.processString(text, context);
  55. }
  56. getUI(id: string, context: [] = []) {
  57. const text = this.getString(id, StringTypes.UI);
  58. return this.processString(text, context);
  59. }
  60. processString(text: string, context: []) {
  61. for (let i = 0; i < context.length; i++) {
  62. const v = context[i];
  63. text = text.replace("$" + i, v);
  64. }
  65. return text;
  66. }
  67. updateTagText(func: ((str: string | null) => string) | null = null): void {
  68. if (this.document !== null) {
  69. const list = this.document.querySelectorAll("data.i18n");
  70. list.forEach((node) => {
  71. if (func === null) {
  72. node.innerHTML = this.processTagTex(node.getAttribute("value"));
  73. } else {
  74. node.innerHTML = func(node.getAttribute("value"));
  75. }
  76. });
  77. }
  78. }
  79. processTagTex(text: string | null): string {
  80. if (text === null) {
  81. return "<Invalid i18n identifier>";
  82. }
  83. const opts = text.split(":");
  84. const type = opts[0].toLowerCase();
  85. const id = opts[1];
  86. if (StringTypes.ERROR === type) {
  87. return this.getError(id);
  88. } else if (StringTypes.MESSAGE === type) {
  89. return this.getMessage(id);
  90. } else if (StringTypes.UI === type) {
  91. return this.getUI(id);
  92. } else {
  93. console.warn(
  94. " A string has been passed to the i18n helper function that was not in the form type:id -> " +
  95. text
  96. );
  97. return this.getString(id, type);
  98. }
  99. }
  100. }