Skip to content

Commit 57c3500

Browse files
committed
build
1 parent c62476f commit 57c3500

2 files changed

Lines changed: 36 additions & 17 deletions

File tree

react-i18next.js

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
const deepExtend = (target, source, overwrite) => {
9898
for (const prop in source) {
9999
if (prop !== '__proto__' && prop !== 'constructor') {
100-
if (prop in target) {
100+
if (Object.prototype.hasOwnProperty.call(target, prop)) {
101101
if (isString$1(target[prop]) || target[prop] instanceof String || isString$1(source[prop]) || source[prop] instanceof String) {
102102
if (overwrite) target[prop] = source[prop];
103103
} else {
@@ -461,11 +461,15 @@
461461
} = selector(createProxy());
462462
const keySeparator = opts?.keySeparator ?? '.';
463463
const nsSeparator = opts?.nsSeparator ?? ':';
464+
const strict = opts?.enableSelector === 'strict';
464465
if (path.length > 1 && nsSeparator) {
465466
const ns = opts?.ns;
466-
const nsArray = Array.isArray(ns) ? ns : null;
467-
if (nsArray && nsArray.length > 1 && nsArray.slice(1).includes(path[0])) {
468-
return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
467+
const nsList = strict ? Array.isArray(ns) ? ns : ns ? [ns] : null : Array.isArray(ns) ? ns : null;
468+
if (nsList) {
469+
const candidates = strict ? nsList : nsList.length > 1 ? nsList.slice(1) : [];
470+
if (candidates.includes(path[0])) {
471+
return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
472+
}
469473
}
470474
}
471475
return path.join(keySeparator);
@@ -877,7 +881,10 @@
877881
const useOptionsReplaceForData = options.replace && !isString$1(options.replace);
878882
let data = useOptionsReplaceForData ? options.replace : options;
879883
if (useOptionsReplaceForData && typeof options.count !== 'undefined') {
880-
data.count = options.count;
884+
data = {
885+
...data,
886+
count: options.count
887+
};
881888
}
882889
if (this.options.interpolation.defaultVariables) {
883890
data = {
@@ -1187,10 +1194,10 @@
11871194
const skipOnVariables = options?.interpolation?.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
11881195
const todos = [{
11891196
regex: this.regexpUnescape,
1190-
safeValue: val => regexSafe(val)
1197+
safeValue: val => val
11911198
}, {
11921199
regex: this.regexp,
1193-
safeValue: val => this.escapeValue ? regexSafe(this.escape(val)) : regexSafe(val)
1200+
safeValue: val => this.escapeValue ? this.escape(val) : val
11941201
}];
11951202
todos.forEach(todo => {
11961203
replaces = 0;
@@ -1214,9 +1221,9 @@
12141221
value = makeString(value);
12151222
}
12161223
const safeValue = todo.safeValue(value);
1217-
str = str.replace(match[0], safeValue);
1224+
str = str.replace(match[0], regexSafe(safeValue));
12181225
if (skipOnVariables) {
1219-
todo.regex.lastIndex += value.length;
1226+
todo.regex.lastIndex += safeValue.length;
12201227
todo.regex.lastIndex -= match[0].length;
12211228
} else {
12221229
todo.regex.lastIndex = 0;
@@ -1266,7 +1273,7 @@
12661273
clonedOptions = clonedOptions.replace && !isString$1(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
12671274
clonedOptions.applyPostProcessor = false;
12681275
delete clonedOptions.defaultValue;
1269-
const keyEndIndex = /{.*}/.test(match[1]) ? match[1].lastIndexOf('}') + 1 : match[1].indexOf(this.formatSeparator);
1276+
const keyEndIndex = /{.*}/s.test(match[1]) ? match[1].lastIndexOf('}') + 1 : match[1].indexOf(this.formatSeparator);
12701277
if (keyEndIndex !== -1) {
12711278
formatters = match[1].slice(keyEndIndex).split(this.formatSeparator).map(elem => elem.trim()).filter(Boolean);
12721279
match[1] = match[1].slice(0, keyEndIndex);
@@ -1395,10 +1402,14 @@
13951402
format(value, format, lng, options = {}) {
13961403
if (!format) return value;
13971404
if (value == null) return value;
1398-
const formats = format.split(this.formatSeparator);
1399-
if (formats.length > 1 && formats[0].indexOf('(') > 1 && !formats[0].includes(')') && formats.find(f => f.includes(')'))) {
1400-
const lastIndex = formats.findIndex(f => f.includes(')'));
1401-
formats[0] = [formats[0], ...formats.splice(1, lastIndex)].join(this.formatSeparator);
1405+
const rawFormats = format.split(this.formatSeparator);
1406+
const formats = [];
1407+
for (let i = 0; i < rawFormats.length; i++) {
1408+
let f = rawFormats[i];
1409+
while (f.indexOf('(') > -1 && !f.includes(')') && i + 1 < rawFormats.length) {
1410+
f = `${f}${this.formatSeparator}${rawFormats[++i]}`;
1411+
}
1412+
formats.push(f);
14021413
}
14031414
const result = formats.reduce((mem, f) => {
14041415
const {
@@ -1657,6 +1668,7 @@
16571668
nsSeparator: ':',
16581669
pluralSeparator: '_',
16591670
contextSeparator: '_',
1671+
enableSelector: false,
16601672
partialBundledLanguages: false,
16611673
saveMissing: false,
16621674
updateMissing: false,
@@ -2831,7 +2843,7 @@
28312843
}) {
28322844
const i18n = i18nFromProps || getI18n();
28332845
if (!i18n) {
2834-
warnOnce(i18n, 'NO_I18NEXT_INSTANCE', `Trans: You need to pass in an i18next instance using i18nextReactModule`, {
2846+
warnOnce(i18n, 'NO_I18NEXT_INSTANCE', `Trans: You need to pass in an i18next instance using initReactI18next or by passing it via props or context. In monorepo setups, make sure there is only one instance of react-i18next.`, {
28352847
i18nKey
28362848
});
28372849
return children;
@@ -3579,7 +3591,7 @@
35793591
const i18n = i18nFromProps || i18nFromContext || getI18n();
35803592
if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces();
35813593
if (!i18n) {
3582-
warnOnce(i18n, 'NO_I18NEXT_INSTANCE', 'useTranslation: You will need to pass in an i18next instance by using initReactI18next');
3594+
warnOnce(i18n, 'NO_I18NEXT_INSTANCE', 'useTranslation: You will need to pass in an i18next instance by using initReactI18next or by passing it via props or context. In monorepo setups, make sure there is only one instance of react-i18next.');
35833595
}
35843596
const i18nOptions = React.useMemo(() => ({
35853597
...getDefaults(),
@@ -3701,6 +3713,13 @@
37013713
return arr;
37023714
}, [t, finalI18n, ready, finalI18n.resolvedLanguage, finalI18n.language, finalI18n.languages]);
37033715
if (i18n && useSuspense && !ready) {
3716+
let inDevelopment = false;
3717+
try {
3718+
inDevelopment = "development" !== 'production';
3719+
} catch (e) {}
3720+
if (inDevelopment) {
3721+
warnOnce(i18n, 'SUSPENDED_WHILE_LOADING', 'useTranslation: suspended while translations are loading (useSuspense is true by default). Add a <Suspense> boundary above this component, or set react.useSuspense: false in the i18next init options. https://react.i18next.com/latest/usetranslation-hook');
3722+
}
37043723
throw new Promise(resolve => {
37053724
const onLoaded = () => resolve();
37063725
if (props.lng) {

react-i18next.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)