@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
JavaScript
(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