@uppy/utils
Version:
Shared utility functions for Uppy Core and plugins maintained by the Uppy team.
157 lines (151 loc) • 5.59 kB
JavaScript
function _classPrivateFieldLooseBase(e, t) { if (!{}.hasOwnProperty.call(e, t)) throw new TypeError("attempted to use private field on non-instance"); return e; }
var id = 0;
function _classPrivateFieldLooseKey(e) { return "__private_" + id++ + "_" + e; }
// We're using a generic because languages have different plural rules.
// eslint-disable-next-line no-use-before-define
function insertReplacement(source, rx, replacement) {
const newParts = [];
source.forEach(chunk => {
// When the source contains multiple placeholders for interpolation,
// we should ignore chunks that are not strings, because those
// can be JSX objects and will be otherwise incorrectly turned into strings.
// Without this condition we’d get this: [object Object] hello [object Object] my <button>
if (typeof chunk !== 'string') {
return newParts.push(chunk);
}
return rx[Symbol.split](chunk).forEach((raw, i, list) => {
if (raw !== '') {
newParts.push(raw);
}
// Interlace with the `replacement` value
if (i < list.length - 1) {
newParts.push(replacement);
}
});
});
return newParts;
}
/**
* Takes a string with placeholder variables like `%{smart_count} file selected`
* and replaces it with values from options `{smart_count: 5}`
*
* @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
* taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
*
* @param phrase that needs interpolation, with placeholders
* @param options with values that will be used to replace placeholders
*/
function interpolate(phrase, options) {
const dollarRegex = /\$/g;
const dollarBillsYall = '$$$$';
let interpolated = [phrase];
if (options == null) return interpolated;
for (const arg of Object.keys(options)) {
if (arg !== '_') {
// Ensure replacement value is escaped to prevent special $-prefixed
// regex replace tokens. the "$$$$" is needed because each "$" needs to
// be escaped with "$" itself, and we need two in the resulting output.
let replacement = options[arg];
if (typeof replacement === 'string') {
replacement = dollarRegex[Symbol.replace](replacement, dollarBillsYall);
}
// We create a new `RegExp` each time instead of using a more-efficient
// string replace so that the same argument can be replaced multiple times
// in the same phrase.
interpolated = insertReplacement(interpolated, new RegExp(`%\\{${arg}\\}`, 'g'), replacement);
}
}
return interpolated;
}
const defaultOnMissingKey = key => {
throw new Error(`missing string: ${key}`);
};
/**
* Translates strings with interpolation & pluralization support.
* Extensible with custom dictionaries and pluralization functions.
*
* Borrows heavily from and inspired by Polyglot https://github.com/airbnb/polyglot.js,
* basically a stripped-down version of it. Differences: pluralization functions are not hardcoded
* and can be easily added among with dictionaries, nested objects are used for pluralization
* as opposed to `||||` delimeter
*
* Usage example: `translator.translate('files_chosen', {smart_count: 3})`
*/
var _onMissingKey = /*#__PURE__*/_classPrivateFieldLooseKey("onMissingKey");
var _apply = /*#__PURE__*/_classPrivateFieldLooseKey("apply");
export default class Translator {
constructor(locales, _temp) {
let {
onMissingKey = defaultOnMissingKey
} = _temp === void 0 ? {} : _temp;
Object.defineProperty(this, _apply, {
value: _apply2
});
Object.defineProperty(this, _onMissingKey, {
writable: true,
value: void 0
});
this.locale = {
strings: {},
pluralize(n) {
if (n === 1) {
return 0;
}
return 1;
}
};
if (Array.isArray(locales)) {
locales.forEach(_classPrivateFieldLooseBase(this, _apply)[_apply], this);
} else {
_classPrivateFieldLooseBase(this, _apply)[_apply](locales);
}
_classPrivateFieldLooseBase(this, _onMissingKey)[_onMissingKey] = onMissingKey;
}
/**
* Public translate method
*
* @param key
* @param options with values that will be used later to replace placeholders in string
* @returns string translated (and interpolated)
*/
translate(key, options) {
return this.translateArray(key, options).join('');
}
/**
* Get a translation and return the translated and interpolated parts as an array.
*
* @returns The translated and interpolated parts, in order.
*/
translateArray(key, options) {
let string = this.locale.strings[key];
if (string == null) {
_classPrivateFieldLooseBase(this, _onMissingKey)[_onMissingKey](key);
string = key;
}
const hasPluralForms = typeof string === 'object';
if (hasPluralForms) {
if (options && typeof options.smart_count !== 'undefined') {
const plural = this.locale.pluralize(options.smart_count);
return interpolate(string[plural], options);
}
throw new Error('Attempted to use a string with plural forms, but no value was given for %{smart_count}');
}
if (typeof string !== 'string') {
throw new Error(`string was not a string`);
}
return interpolate(string, options);
}
}
function _apply2(locale) {
if (!(locale != null && locale.strings)) {
return;
}
const prevLocale = this.locale;
Object.assign(this.locale, {
strings: {
...prevLocale.strings,
...locale.strings
},
pluralize: locale.pluralize || prevLocale.pluralize
});
}