{"version":3,"file":"index.mjs","sources":[""],"sourcesContent":["import { getDocument } from \"ssr-window\";\r\nimport { constants } from \"../../constants\";\r\nimport { _isReactNode } from \"../../utils/_isReactNode\";\r\nimport { getAttr } from \"../../utils/getAttr\";\r\nimport { getSanitizedHTML } from \"../../utils/getSanitizedHTML\";\r\nimport { Collection } from \"../collection\";\r\nimport type { TCollectionElement } from \"../collection\";\r\nimport { CollectionItem } from \"../collectionItem\";\r\nimport { Localisation } from \"../localisation\";\r\nimport type { TLocalisationEvent } from \"../localisation/types\";\r\n\r\ntype TCollectionArgs = [ string, typeof Locale, boolean? ];\r\n\r\ntype TLocaleCfg = {\r\n  code?: string;\r\n  attr?: string | string[];\r\n  options?: Record<string, unknown>;\r\n};\r\n\r\nconst isLocalisationEvent = (event: Event): event is TLocalisationEvent<Localisation> => {\r\n  return event instanceof CustomEvent && typeof event.detail === \"object\" && event.detail !== null;\r\n};\r\n\r\nconst setupLocalisationInstance = (e: TLocalisationEvent<Localisation>) => {\r\n  const instance = e && isLocalisationEvent(e) ? e.detail.instance : null;\r\n  if (instance && !LocaleCollection.localisationInstance) {\r\n    LocaleCollection.localisationInstance = instance;\r\n  }\r\n};\r\n\r\n/**\r\n * Класс для рендеринга элемента локали статичной разметки\r\n */\r\nexport class Locale extends CollectionItem<TLocaleCfg> {\r\n\r\n  states: {\r\n    lastTransition: string | null;\r\n  };\r\n\r\n  isReact: boolean;\r\n\r\n  constructor(el: TCollectionElement) {\r\n    if (!(el instanceof HTMLElement)) {\r\n      throw new TypeError(`[LocaleCollection] HTMLElement is expected, but got \"${el?.constructor?.name || typeof el}\"`);\r\n    }\r\n    super(el, LocaleCollection.selector);\r\n    this.states = {\r\n      lastTransition: null,\r\n    };\r\n    this.isReact = _isReactNode(el);\r\n    if (!this.isReact) {\r\n      this.instance.classList.add(constants.stateClasses.translationLoading);\r\n      if (LocaleCollection.localisationInstance) {\r\n        this.translate = this.locale;\r\n      } else {\r\n        Localisation.onReady = this.#onLocalisationReady.bind(this);\r\n      }\r\n    }\r\n  }\r\n\r\n  #onLocalisationReady(instance: Localisation) {\r\n    LocaleCollection.localisationInstance = instance;\r\n    this.translate = this.locale;\r\n  }\r\n\r\n  get attr() {\r\n    const isValidStr = (str: unknown): str is string => typeof str === \"string\" && !!str.length;\r\n    const { attr } = this.cfg;\r\n    if (isValidStr(attr)) {\r\n      return attr;\r\n    }\r\n    if (Array.isArray(attr) && attr.every(isValidStr)) {\r\n      return attr;\r\n    }\r\n    return null;\r\n  }\r\n\r\n  get options(): Record<string, unknown> {\r\n    return (typeof this.cfg.options === \"object\" && this.cfg.options !== null) ? this.cfg.options : {};\r\n  }\r\n\r\n  get locale(): string {\r\n    if (this.code && LocaleCollection.localisationInstance) {\r\n      const instance = LocaleCollection.localisationInstance;\r\n      return instance.getLocale(this.code, this.options);\r\n    }\r\n    return \"\";\r\n  }\r\n\r\n  set translate(msg: string) {\r\n    if (!!msg && this.states.lastTransition !== msg) {\r\n      if (this.isReact) { // react render\r\n        if (this.instance.classList.contains(constants.stateClasses.translationLoading)) {\r\n          console.error(`[LocaleCollection] Detected unfinished locale render. You need to await \"Localisation\" plugin before render locales`, this.instance);\r\n        }\r\n      } else { // static markup\r\n        const attr = this.attr;\r\n        if (attr) {\r\n          Array.from(this.instance.children).forEach((node) => {\r\n            const userAttrs = typeof attr === \"string\"\r\n              ? Localisation.utils.getUserAttrs({ [attr]: msg })\r\n              : Localisation.utils.getUserAttrs(Object.fromEntries(attr.map((currentAttr) => [ currentAttr, msg ])));\r\n\r\n            Object.entries(userAttrs).forEach(([ key, value ]) => {\r\n              node.setAttribute(key, String(value));\r\n            });\r\n          });\r\n        } else {\r\n          if (this.instance.innerHTML !== msg) {\r\n            this.instance.innerHTML = getSanitizedHTML(msg);\r\n          }\r\n        }\r\n        this.instance.classList.remove(constants.stateClasses.translationLoading);\r\n        this.instance.classList.add(constants.stateClasses.translated);\r\n        this.states.lastTransition = msg;\r\n      }\r\n    }\r\n  }\r\n\r\n  get code(): string | null {\r\n    const cfgCode = (typeof this.cfg.code === \"string\" && this.cfg.code.length) ? this.cfg.code : null;\r\n    return cfgCode || this.instance.getAttribute(getAttr(LocaleCollection.selector));\r\n  }\r\n\r\n}\r\n\r\n/**\r\n * Коллекция вызовов локализации для статичной разметки (режима SSG).\r\n * Следует запускать после инициализации плагина `Localisation`\r\n */\r\nexport class LocaleCollection extends Collection<Locale> {\r\n\r\n  /**\r\n   * Признак регистрации коллекции в глобальном namespace Core.\r\n   * @type {boolean}\r\n   */\r\n  static isApp = true;\r\n\r\n  /**\r\n   * Текущий экземпляр плагина Localisation, используемый для перевода элементов коллекции.\r\n   * @type {Localisation|null}\r\n   */\r\n  static localisationInstance: Localisation | null = null;\r\n\r\n  /**\r\n   * CSS-селектор элементов локализации для автоподключения коллекции.\r\n   * @type {string}\r\n   */\r\n  static selector = \"[data-js-locale]\";\r\n\r\n  constructor(...args: TCollectionArgs) {\r\n    const defaultArgs: TCollectionArgs = [ LocaleCollection.selector, Locale, true ];\r\n    const finalArgs = args.length ? args : defaultArgs;\r\n    super(...finalArgs);\r\n    Localisation.onReady = this.#onLocalisationReady.bind(this);\r\n  }\r\n\r\n  /**\r\n   * Защищает React-элементы от попадания в статичную коллекцию\r\n   * @returns {Boolean}\r\n   */\r\n  isValid(el: TCollectionElement): boolean {\r\n    return !_isReactNode(el);\r\n  }\r\n\r\n  watchUpdates() {\r\n    getDocument().addEventListener(constants.localisationBubbles.localisationChange, this.#onLocalisationChange.bind(this));\r\n  }\r\n\r\n  #onLocalisationChange(e: TLocalisationEvent<Localisation>) {\r\n    setupLocalisationInstance(e);\r\n    this.update();\r\n  }\r\n\r\n  #onLocalisationReady(instance: Localisation) {\r\n    LocaleCollection.localisationInstance = instance;\r\n    this.watchUpdates();\r\n    this.update();\r\n  }\r\n\r\n  update() {\r\n    if (LocaleCollection.localisationInstance) {\r\n      this.collection.forEach((instance) => {\r\n        const code = instance.code;\r\n        const options = instance.options;\r\n        if (code) {\r\n          const msg = LocaleCollection.localisationInstance!.getLocale(code, options) || \"\";\r\n          if (msg) {\r\n            instance.translate = msg;\r\n          } else {\r\n            console.error(`[LocaleCollection] Missing locale for code \"${code}\"`);\r\n          }\r\n        } else {\r\n          console.error(`[LocaleCollection] Missing \"code\" prop for element`, instance.instance);\r\n        }\r\n      });\r\n    } else {\r\n      console.error(`[LocaleCollection] Can't do update, Localisation plugin is not ready`);\r\n    }\r\n  }\r\n\r\n}\r\n"],"names":["isLocalisationEvent","event","CustomEvent","detail","setupLocalisationInstance","e","instance","LocaleCollection","localisationInstance","Locale","CollectionItem","states","isReact","constructor","el","HTMLElement","TypeError","name","super","selector","this","lastTransition","_isReactNode","classList","add","constants","stateClasses","translationLoading","translate","locale","Localisation","onReady","onLocalisationReady","bind","attr","isValidStr","str","length","cfg","Array","isArray","every","options","code","getLocale","msg","contains","console","error","from","children","forEach","node","userAttrs","utils","getUserAttrs","Object","fromEntries","map","currentAttr","entries","key","value","setAttribute","String","innerHTML","getSanitizedHTML","remove","translated","cfgCode","getAttribute","getAttr","Collection","static","args","defaultArgs","finalArgs","isValid","watchUpdates","getDocument","addEventListener","localisationBubbles","localisationChange","onLocalisationChange","update","collection"],"mappings":"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"}