UNPKG

@atlassian/wrm-react-i18n

Version:

An internationalization i18n helper for WRM and React that can be used in Atlassian Server products

90 lines (85 loc) 4.47 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('wrm/format')) : typeof define === 'function' && define.amd ? define(['exports', 'react', 'wrm/format'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@atlassian/wrm-react-i18n"] = {}, global.React, global.wrmFormat)); })(this, (function (exports, React, wrmFormat) { 'use strict'; // backward-compatibility with WRM < 4.2 where wrm/i18n is not available yet const WrmI18n = function () { try { // eslint-disable-next-line @typescript-eslint/no-var-requires return require('wrm/i18n'); // A module provided in browser runtime by WRM >= 4.2 } catch (e) { return null; } }(); function format(translation, ...args) { let i = 0; const mapping = {}; const mappedArgs = args.map(arg => { if (/*#__PURE__*/React.isValidElement(arg)) { const str = `!PLACEHOLDER_${++i}!`; mapping[str] = arg; return str; } return arg; }); const strParts = wrmFormat(translation, ...mappedArgs).split(/(!PLACEHOLDER_\d+!)/g); if (strParts.length === 1) { return strParts.join(''); } const asReactEls = strParts.map((str, idx) => { return /*#__PURE__*/React.createElement(React.Fragment, { key: idx }, idx % 2 ? mapping[str] : str); }); return /*#__PURE__*/React.createElement(React.Fragment, null, asReactEls); } const getText = (key, ...args) => { /** * What's going on here? There are two scenarios to consider: * 1) Regular i18n mechanism replacing "<>.getText(...)" at run-time on the back-end side; * it's an error when the execution enters this function and a message in the console * will be printed (coming from WRM code), in the UI raw i18n key will be displayed. * 2) When WRM two-phases i18n mechanism is used, it's expected that execution enters * this function and we need to call the original WRM's getText function, because * it holds the i18n->translation Map (the translation is done at the client-side); * however this package 'wrm-react-i18n' adds a support for React components by * providing a different 'format' function; hence a problem in 2) scenario, because * by calling the original WRM's getText function, the original WRM's format function * is also called. That's why we're swapping the WRM's format function to the * React-enhanced version of it, due to the lack of a better alternative atm. * The swap is done just for a single execution of WRM's getText function; * all the code is synchronous, hence there's no chance of affecting other places; * in other words the swap is atomic / completely transparent to the outside world. * 3) At run-times with WRM < 4.2, "wrm/i18n" module is not available yet, in this case * falling back to the previous implementation: calling enhanced 'format' function. */ // for WRM < 4.2 if (!WrmI18n) { // The warning should be kept in production bundle if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') { console.warn('Call to "getText" function was not replaced with either raw translation or call to "format" function. Have you included the "jsI18n" transformation in Web Resource Manager?'); } return format(key, ...args); } // for WRM >= 4.2 let result; try { WRM.I18n.format = format; result = WrmI18n.getText.apply(null, [key, ...args]); } finally { WRM.I18n.format = wrmFormat; } return result; }; // We need to re-export the fake "getText" since "<<namespace>>.I18n.getText()" is used in the source code and then // replaced to "<<namespace>>.format()" by either jsI18n transformer or @atlassian/i18n-properties-loader webpack loader. // However, when two-phases i18n is used (since WRM 5.3+/AMPS 8.3+) "<<namespace>>.I18n.getText()" is not replaced and // "getText" should call the original "getText" function from WRM. const I18n = { getText }; exports.I18n = I18n; exports.format = format; })); //# sourceMappingURL=wrm-react-i18n.js.map