t9n.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.97
  5. */
  6. import { getAssetPath } from "@stencil/core";
  7. import { getSupportedLocale } from "./locale";
  8. export const componentLangToMessageBundleCache = {};
  9. async function getMessageBundle(lang, component) {
  10. const key = `${component}_${lang}`;
  11. if (componentLangToMessageBundleCache[key]) {
  12. return componentLangToMessageBundleCache[key];
  13. }
  14. componentLangToMessageBundleCache[key] = fetch(getAssetPath(`./assets/${component}/t9n/messages_${lang}.json`))
  15. .then((resp) => {
  16. if (!resp.ok) {
  17. throwMessageFetchError();
  18. }
  19. return resp.json();
  20. })
  21. .catch(() => throwMessageFetchError());
  22. return componentLangToMessageBundleCache[key];
  23. }
  24. function throwMessageFetchError() {
  25. throw new Error("could not fetch component message bundle");
  26. }
  27. /**
  28. * This util helps preserve existing intlProp usage when they have not been replaced by overrides.
  29. *
  30. * @param component
  31. */
  32. export function overridesFromIntlProps(component) {
  33. const { el } = component;
  34. const overrides = {};
  35. Object.keys(el.constructor.prototype)
  36. .filter((prop) => prop.startsWith("intl"))
  37. .forEach((prop) => {
  38. const assignedValue = el[prop];
  39. if (assignedValue) {
  40. let mappedProp = prop.replace("intl", "");
  41. mappedProp = `${mappedProp[0].toLowerCase()}${mappedProp.slice(1)}`;
  42. overrides[mappedProp] = assignedValue;
  43. }
  44. });
  45. return overrides;
  46. }
  47. function mergeMessages(component) {
  48. component.messages = {
  49. ...component.defaultMessages,
  50. ...getEffectiveMessageOverrides(component)
  51. };
  52. }
  53. function getEffectiveMessageOverrides(component) {
  54. var _a;
  55. return (_a = component.messageOverrides) !== null && _a !== void 0 ? _a : overridesFromIntlProps(component);
  56. }
  57. /**
  58. * This utility sets up the messages used by the component. It should be awaited in the `componentWillLoad` lifecycle hook.
  59. *
  60. * @param component
  61. */
  62. export async function setUpMessages(component) {
  63. component.defaultMessages = await fetchMessages(component, component.effectiveLocale);
  64. mergeMessages(component);
  65. }
  66. async function fetchMessages(component, lang) {
  67. const { el } = component;
  68. const tag = el.tagName.toLowerCase();
  69. const componentName = tag.replace("calcite-", "");
  70. return getMessageBundle(getSupportedLocale(lang), componentName);
  71. }
  72. /**
  73. * This utility must be set up for the component to update its default message bundle if the locale changes.
  74. *
  75. * It can be set up in **either** of the following ways:
  76. *
  77. * 1. called from `LocalizedComponent`'s `onLocaleChange` method or
  78. * 2. called from a watcher configured to watch `LocalizedComponent`'s `effectiveLocale` prop
  79. *
  80. * @param component
  81. * @param lang
  82. */
  83. export async function updateMessages(component, lang) {
  84. component.defaultMessages = await fetchMessages(component, lang);
  85. }
  86. /**
  87. * This utility sets up internals for messages support.
  88. *
  89. * It needs to be called in `connectedCallback`
  90. *
  91. * **Note**: this must be called after `LocalizedComponent`'s `connectLocalized` method.
  92. *
  93. * @param component
  94. */
  95. export function connectMessages(component) {
  96. component.onMessagesChange = defaultOnMessagesChange;
  97. }
  98. /**
  99. * This utility tears down internals for messages support.
  100. *
  101. * It needs to be called in `disconnectedCallback`
  102. *
  103. * @param component
  104. */
  105. export function disconnectMessages(component) {
  106. component.onMessagesChange = undefined;
  107. }
  108. function defaultOnMessagesChange() {
  109. mergeMessages(this);
  110. }