I18N.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /**
  2. * Localizer.js
  3. *
  4. * @author realor
  5. */
  6. import { Bundle } from './Bundle.js'
  7. import { BundleManager } from './BundleManager.js'
  8. class I18N {
  9. static SEPARATOR = '|'
  10. _userLanguages = ['zh-CN']
  11. _requestedLanguages = null
  12. _supportedLanguages = new Set()
  13. defaultBundle = BundleManager.getBundle('base')
  14. constructor() {}
  15. static set(element, property, key, ...args) {
  16. if (element.i18n === undefined) {
  17. element.i18n = {}
  18. }
  19. element.i18n[property] = {
  20. key: key,
  21. args: args
  22. }
  23. element[property] = key
  24. }
  25. addSupportedLanguages(...languages) {
  26. for (let language of languages) {
  27. this._supportedLanguages.add(language)
  28. }
  29. this._requestedLanguages = null
  30. }
  31. get supportedLanguages() {
  32. return Array.from(this._supportedLanguages)
  33. }
  34. get userLanguages() {
  35. return this._userLanguages
  36. }
  37. set userLanguages(languages) {
  38. if (typeof languages === 'string') {
  39. this._userLanguages = [languages]
  40. this._requestedLanguages = null
  41. } else if (languages instanceof Array) {
  42. this._userLanguages = languages
  43. this._requestedLanguages = null
  44. }
  45. }
  46. get requestedLanguages() {
  47. if (this._requestedLanguages === null) {
  48. let set = new Set()
  49. this.userLanguages.forEach(language => {
  50. if (this._supportedLanguages.has(language)) {
  51. set.add(language)
  52. }
  53. let parts = language.split('-')
  54. if (parts.length > 1) {
  55. if (this._supportedLanguages.has(parts[0])) {
  56. set.add(parts[0])
  57. }
  58. }
  59. })
  60. set.add('') // default language
  61. this._requestedLanguages = Array.from(set)
  62. }
  63. return this._requestedLanguages
  64. }
  65. get(key, ...args) {
  66. if (typeof key !== 'string') return ''
  67. let bundle = null
  68. let index = key.indexOf(I18N.SEPARATOR)
  69. if (index === -1) {
  70. bundle = this.defaultBundle
  71. } else {
  72. bundle = BundleManager.getBundle(key.substring(0, index))
  73. key = key.substring(index + 1)
  74. }
  75. return bundle ? bundle.get(this.requestedLanguages, key, ...args) : key
  76. }
  77. updateTree(rootElement) {
  78. const promises = []
  79. const bundles = BundleManager.getBundles()
  80. bundles.forEach(bundle => {
  81. let promise = bundle.load(this.requestedLanguages)
  82. promises.push(promise)
  83. })
  84. Promise.allSettled(promises).finally(() => {
  85. const elements = rootElement.getElementsByTagName('*')
  86. for (let element of elements) {
  87. this.update(element)
  88. }
  89. })
  90. }
  91. update(element) {
  92. if (element.i18n) {
  93. for (let property in element.i18n) {
  94. let def = element.i18n[property]
  95. element[property] = this.get(def.key, ...def.args)
  96. }
  97. }
  98. }
  99. }
  100. export { I18N }