react-i18next 17.0.9 → 17.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/react-i18next.js CHANGED
@@ -97,7 +97,7 @@
97
97
  const deepExtend = (target, source, overwrite) => {
98
98
  for (const prop in source) {
99
99
  if (prop !== '__proto__' && prop !== 'constructor') {
100
- if (prop in target) {
100
+ if (Object.prototype.hasOwnProperty.call(target, prop)) {
101
101
  if (isString$1(target[prop]) || target[prop] instanceof String || isString$1(source[prop]) || source[prop] instanceof String) {
102
102
  if (overwrite) target[prop] = source[prop];
103
103
  } else {
@@ -461,11 +461,15 @@
461
461
  } = selector(createProxy());
462
462
  const keySeparator = opts?.keySeparator ?? '.';
463
463
  const nsSeparator = opts?.nsSeparator ?? ':';
464
+ const strict = opts?.enableSelector === 'strict';
464
465
  if (path.length > 1 && nsSeparator) {
465
466
  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
+ }
469
473
  }
470
474
  }
471
475
  return path.join(keySeparator);
@@ -877,7 +881,10 @@
877
881
  const useOptionsReplaceForData = options.replace && !isString$1(options.replace);
878
882
  let data = useOptionsReplaceForData ? options.replace : options;
879
883
  if (useOptionsReplaceForData && typeof options.count !== 'undefined') {
880
- data.count = options.count;
884
+ data = {
885
+ ...data,
886
+ count: options.count
887
+ };
881
888
  }
882
889
  if (this.options.interpolation.defaultVariables) {
883
890
  data = {
@@ -1187,10 +1194,10 @@
1187
1194
  const skipOnVariables = options?.interpolation?.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
1188
1195
  const todos = [{
1189
1196
  regex: this.regexpUnescape,
1190
- safeValue: val => regexSafe(val)
1197
+ safeValue: val => val
1191
1198
  }, {
1192
1199
  regex: this.regexp,
1193
- safeValue: val => this.escapeValue ? regexSafe(this.escape(val)) : regexSafe(val)
1200
+ safeValue: val => this.escapeValue ? this.escape(val) : val
1194
1201
  }];
1195
1202
  todos.forEach(todo => {
1196
1203
  replaces = 0;
@@ -1214,9 +1221,9 @@
1214
1221
  value = makeString(value);
1215
1222
  }
1216
1223
  const safeValue = todo.safeValue(value);
1217
- str = str.replace(match[0], safeValue);
1224
+ str = str.replace(match[0], regexSafe(safeValue));
1218
1225
  if (skipOnVariables) {
1219
- todo.regex.lastIndex += value.length;
1226
+ todo.regex.lastIndex += safeValue.length;
1220
1227
  todo.regex.lastIndex -= match[0].length;
1221
1228
  } else {
1222
1229
  todo.regex.lastIndex = 0;
@@ -1266,7 +1273,7 @@
1266
1273
  clonedOptions = clonedOptions.replace && !isString$1(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
1267
1274
  clonedOptions.applyPostProcessor = false;
1268
1275
  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);
1270
1277
  if (keyEndIndex !== -1) {
1271
1278
  formatters = match[1].slice(keyEndIndex).split(this.formatSeparator).map(elem => elem.trim()).filter(Boolean);
1272
1279
  match[1] = match[1].slice(0, keyEndIndex);
@@ -1395,10 +1402,14 @@
1395
1402
  format(value, format, lng, options = {}) {
1396
1403
  if (!format) return value;
1397
1404
  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);
1402
1413
  }
1403
1414
  const result = formats.reduce((mem, f) => {
1404
1415
  const {
@@ -1657,6 +1668,7 @@
1657
1668
  nsSeparator: ':',
1658
1669
  pluralSeparator: '_',
1659
1670
  contextSeparator: '_',
1671
+ enableSelector: false,
1660
1672
  partialBundledLanguages: false,
1661
1673
  saveMissing: false,
1662
1674
  updateMissing: false,
@@ -2233,127 +2245,318 @@
2233
2245
  instance.loadNamespaces;
2234
2246
  instance.loadLanguages;
2235
2247
 
2236
- function getDefaultExportFromCjs (x) {
2237
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
2248
+ const voidElements = {
2249
+ area: true,
2250
+ base: true,
2251
+ br: true,
2252
+ col: true,
2253
+ embed: true,
2254
+ hr: true,
2255
+ img: true,
2256
+ input: true,
2257
+ link: true,
2258
+ meta: true,
2259
+ param: true,
2260
+ source: true,
2261
+ track: true,
2262
+ wbr: true,
2263
+ '!doctype': true,
2264
+ '!DOCTYPE': true
2265
+ };
2266
+ const attrRE = /\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?("[^"]*"|'[^']*')/g;
2267
+ function parseTag(tag) {
2268
+ const res = {
2269
+ type: 'tag',
2270
+ name: '',
2271
+ voidElement: false,
2272
+ attrs: {},
2273
+ children: []
2274
+ };
2275
+ const tagMatch = tag.match(/<\/?([^\s]+?)[/\s>]/);
2276
+ if (tagMatch) {
2277
+ res.name = tagMatch[1];
2278
+ if (voidElements[tagMatch[1]] || tag.charAt(tag.length - 2) === '/') {
2279
+ res.voidElement = true;
2280
+ }
2281
+ if (res.name.startsWith('!--')) {
2282
+ const endIndex = tag.indexOf('-->');
2283
+ return {
2284
+ type: 'comment',
2285
+ comment: endIndex !== -1 ? tag.slice(4, endIndex) : ''
2286
+ };
2287
+ }
2288
+ }
2289
+ const reg = new RegExp(attrRE);
2290
+ let result = null;
2291
+ for (;;) {
2292
+ result = reg.exec(tag);
2293
+ if (result === null) {
2294
+ break;
2295
+ }
2296
+ if (!result[0].trim()) {
2297
+ continue;
2298
+ }
2299
+ if (result[1]) {
2300
+ const attr = result[1].trim();
2301
+ let arr = [attr, null];
2302
+ const eq = attr.indexOf('=');
2303
+ if (eq > -1) {
2304
+ arr = [attr.slice(0, eq), attr.slice(eq + 1)];
2305
+ }
2306
+ res.attrs[arr[0]] = arr[1];
2307
+ reg.lastIndex--;
2308
+ } else if (result[2]) {
2309
+ res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1);
2310
+ }
2311
+ }
2312
+ return res;
2238
2313
  }
2239
-
2240
- var voidElements;
2241
- var hasRequiredVoidElements;
2242
-
2243
- function requireVoidElements () {
2244
- if (hasRequiredVoidElements) return voidElements;
2245
- hasRequiredVoidElements = 1;
2246
- voidElements = {
2247
- "area": true,
2248
- "base": true,
2249
- "br": true,
2250
- "col": true,
2251
- "embed": true,
2252
- "hr": true,
2253
- "img": true,
2254
- "input": true,
2255
- "link": true,
2256
- "meta": true,
2257
- "param": true,
2258
- "source": true,
2259
- "track": true,
2260
- "wbr": true
2261
- };
2262
- return voidElements;
2314
+ const tagRE = /<!--[\s\S]*?-->|<[a-zA-Z0-9\-!/](?:"[^"]*"|'[^']*'|[^'">])*>/g;
2315
+ const tagNameRE = /<\/?([^\s]+?)[/\s>]/;
2316
+ const whitespaceRE = /^\s*$/;
2317
+ const rawTextRE = /^(script|style)$/i;
2318
+ const sentinel = '\u0000';
2319
+ const empty = Object.create(null);
2320
+ function restoreSentinels(nodes) {
2321
+ nodes.forEach(function (node) {
2322
+ if (node.type === 'text') {
2323
+ node.content = node.content.split(sentinel).join('<');
2324
+ return;
2325
+ }
2326
+ if (node.type === 'comment') {
2327
+ node.comment = node.comment.split(sentinel).join('<');
2328
+ return;
2329
+ }
2330
+ for (const key in node.attrs) {
2331
+ const value = node.attrs[key];
2332
+ if (typeof value === 'string' && value.indexOf(sentinel) > -1) {
2333
+ node.attrs[key] = value.split(sentinel).join('<');
2334
+ }
2335
+ }
2336
+ if (node.children.length) {
2337
+ restoreSentinels(node.children);
2338
+ }
2339
+ });
2263
2340
  }
2264
-
2265
- var voidElementsExports = requireVoidElements();
2266
- var e = /*@__PURE__*/getDefaultExportFromCjs(voidElementsExports);
2267
-
2268
- var t = /\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;
2269
- function n(n) {
2270
- var r = {
2271
- type: "tag",
2272
- name: "",
2273
- voidElement: false,
2274
- attrs: {},
2275
- children: []
2276
- },
2277
- i = n.match(/<\/?([^\s]+?)[/\s>]/);
2278
- if (i && (r.name = i[1], (e[i[1]] || "/" === n.charAt(n.length - 2)) && (r.voidElement = true), r.name.startsWith("!--"))) {
2279
- var s = n.indexOf("--\x3e");
2280
- return {
2281
- type: "comment",
2282
- comment: -1 !== s ? n.slice(4, s) : ""
2341
+ function parse(html, options) {
2342
+ const components = options && options.components || empty;
2343
+ const allowedTags = options && options.allowedTags;
2344
+ let restoreNeeded = false;
2345
+ if (allowedTags) {
2346
+ const isAllowed = typeof allowedTags === 'function' ? allowedTags : function (name) {
2347
+ return allowedTags.indexOf(name) > -1;
2283
2348
  };
2349
+ let out = '';
2350
+ let pos = 0;
2351
+ tagRE.lastIndex = 0;
2352
+ let am;
2353
+ while (am = tagRE.exec(html)) {
2354
+ const tag = am[0];
2355
+ out += html.slice(pos, am.index);
2356
+ const nameMatch = tag.match(tagNameRE);
2357
+ if (tag.startsWith('<!--') || nameMatch && isAllowed(nameMatch[1])) {
2358
+ out += tag;
2359
+ pos = am.index + tag.length;
2360
+ } else {
2361
+ restoreNeeded = true;
2362
+ out += sentinel;
2363
+ pos = am.index + 1;
2364
+ tagRE.lastIndex = pos;
2365
+ }
2366
+ }
2367
+ html = out + html.slice(pos);
2284
2368
  }
2285
- for (var a = new RegExp(t), c = null; null !== (c = a.exec(n));) if (c[0].trim()) if (c[1]) {
2286
- var o = c[1].trim(),
2287
- l = [o, ""];
2288
- o.indexOf("=") > -1 && (l = o.split("=")), r.attrs[l[0]] = l[1], a.lastIndex--;
2289
- } else c[2] && (r.attrs[c[2]] = c[3].trim().substring(1, c[3].length - 1));
2290
- return r;
2291
- }
2292
- var r = /<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,
2293
- i = /^\s*$/,
2294
- s = Object.create(null);
2295
- function a(e, t) {
2296
- switch (t.type) {
2297
- case "text":
2298
- return e + t.content;
2299
- case "tag":
2300
- return e += "<" + t.name + (t.attrs ? function (e) {
2301
- var t = [];
2302
- for (var n in e) t.push(n + '="' + e[n] + '"');
2303
- return t.length ? " " + t.join(" ") : "";
2304
- }(t.attrs) : "") + (t.voidElement ? "/>" : ">"), t.voidElement ? e : e + t.children.reduce(a, "") + "</" + t.name + ">";
2305
- case "comment":
2306
- return e + "\x3c!--" + t.comment + "--\x3e";
2369
+ const result = [];
2370
+ const arr = [];
2371
+ let current;
2372
+ let level = -1;
2373
+ let inComponent = false;
2374
+ let rawUntil = 0;
2375
+ let htmlLower;
2376
+ if (html.indexOf('<') !== 0) {
2377
+ const end = html.indexOf('<');
2378
+ result.push({
2379
+ type: 'text',
2380
+ content: end === -1 ? html : html.substring(0, end)
2381
+ });
2307
2382
  }
2308
- }
2309
- var c = {
2310
- parse: function (e, t) {
2311
- t || (t = {}), t.components || (t.components = s);
2312
- var a,
2313
- c = [],
2314
- o = [],
2315
- l = -1,
2316
- m = false;
2317
- if (0 !== e.indexOf("<")) {
2318
- var u = e.indexOf("<");
2319
- c.push({
2320
- type: "text",
2321
- content: -1 === u ? e : e.substring(0, u)
2322
- });
2383
+ const matches = [];
2384
+ let m;
2385
+ while (m = tagRE.exec(html)) {
2386
+ matches.push(m);
2387
+ }
2388
+ matches.forEach(function (match, i) {
2389
+ const tag = match[0];
2390
+ if (!tag) return;
2391
+ if (tag.startsWith('<!--')) return;
2392
+ let lts = 0;
2393
+ let gts = 0;
2394
+ let secondLt = -1;
2395
+ let quote = null;
2396
+ for (let j = 0; j < tag.length; j++) {
2397
+ const c = tag.charAt(j);
2398
+ if (quote) {
2399
+ if (c === quote) quote = null;
2400
+ } else if (c === '"' || c === "'") {
2401
+ quote = c;
2402
+ } else if (c === '<') {
2403
+ lts++;
2404
+ if (lts === 2) secondLt = j;
2405
+ } else if (c === '>') {
2406
+ gts++;
2407
+ }
2408
+ }
2409
+ const validSplit = secondLt > -1 && /[a-zA-Z0-9\-!/]/.test(tag.charAt(secondLt + 1));
2410
+ if (lts > gts && validSplit) {
2411
+ const firstPart = tag.substring(0, secondLt);
2412
+ const secondPart = tag.substring(firstPart.length);
2413
+ matches[i][0] = secondPart;
2414
+ matches[i].index += firstPart.length;
2323
2415
  }
2324
- return e.replace(r, function (r, s) {
2325
- if (m) {
2326
- if (r !== "</" + a.name + ">") return;
2327
- m = false;
2328
- }
2329
- var u,
2330
- f = "/" !== r.charAt(1),
2331
- h = r.startsWith("\x3c!--"),
2332
- p = s + r.length,
2333
- d = e.charAt(p);
2334
- if (h) {
2335
- var v = n(r);
2336
- return l < 0 ? (c.push(v), c) : ((u = o[l]).children.push(v), c);
2337
- }
2338
- if (f && (l++, "tag" === (a = n(r)).type && t.components[a.name] && (a.type = "component", m = true), a.voidElement || m || !d || "<" === d || a.children.push({
2339
- type: "text",
2340
- content: e.slice(p, e.indexOf("<", p))
2341
- }), 0 === l && c.push(a), (u = o[l - 1]) && u.children.push(a), o[l] = a), (!f || a.voidElement) && (l > -1 && (a.voidElement || a.name === r.slice(2, -1)) && (l--, a = -1 === l ? c : o[l]), !m && "<" !== d && d)) {
2342
- u = -1 === l ? c : o[l].children;
2343
- var x = e.indexOf("<", p),
2344
- g = e.slice(p, -1 === x ? void 0 : x);
2345
- i.test(g) && (g = " "), (x > -1 && l + u.length >= 0 || " " !== g) && u.push({
2346
- type: "text",
2347
- content: g
2416
+ });
2417
+ matches.forEach(function (match, i) {
2418
+ const tag = match[0];
2419
+ if (!tag) return;
2420
+ const index = match.index;
2421
+ if (index < rawUntil) return;
2422
+ if (inComponent) {
2423
+ if (tag !== '</' + current.name + '>') {
2424
+ return;
2425
+ } else {
2426
+ inComponent = false;
2427
+ }
2428
+ }
2429
+ const isOpen = tag.charAt(1) !== '/';
2430
+ const isComment = tag.startsWith('<!--');
2431
+ const start = index + tag.length;
2432
+ const nextChar = html.charAt(start);
2433
+ const nextMatch = matches[i + 1];
2434
+ let isText;
2435
+ if (nextChar === '<' && nextMatch) {
2436
+ const nextTag = html.substring(start, nextMatch.index);
2437
+ isText = nextTag.split('<').length > nextTag.split('>').length;
2438
+ }
2439
+ let parent;
2440
+ if (isComment) {
2441
+ const comment = parseTag(tag);
2442
+ if (level < 0) {
2443
+ result.push(comment);
2444
+ return result;
2445
+ }
2446
+ parent = arr[level];
2447
+ parent.children.push(comment);
2448
+ const text = html.slice(start, nextMatch ? nextMatch.index : undefined);
2449
+ if (text.length > 0) {
2450
+ parent.children.push({
2451
+ type: 'text',
2452
+ content: text
2348
2453
  });
2349
2454
  }
2350
- }), c;
2351
- },
2352
- stringify: function (e) {
2353
- return e.reduce(function (e, t) {
2354
- return e + a("", t);
2355
- }, "");
2455
+ return result;
2456
+ }
2457
+ if (isOpen) {
2458
+ level++;
2459
+ current = parseTag(tag);
2460
+ if (current.type === 'tag' && components[current.name]) {
2461
+ current.type = 'component';
2462
+ inComponent = true;
2463
+ }
2464
+ let isRawText = false;
2465
+ if (!inComponent && !current.voidElement && rawTextRE.test(current.name)) {
2466
+ isRawText = true;
2467
+ htmlLower || (htmlLower = html.toLowerCase());
2468
+ const closeIndex = htmlLower.indexOf('</' + current.name.toLowerCase() + '>', start);
2469
+ const contentEnd = closeIndex === -1 ? html.length : closeIndex;
2470
+ const content = html.slice(start, contentEnd);
2471
+ if (content) {
2472
+ current.children.push({
2473
+ type: 'text',
2474
+ content
2475
+ });
2476
+ }
2477
+ rawUntil = contentEnd;
2478
+ }
2479
+ if (!current.voidElement && !inComponent && !isRawText && nextChar && nextChar !== '<') {
2480
+ current.children.push({
2481
+ type: 'text',
2482
+ content: html.slice(start, nextMatch ? nextMatch.index : undefined)
2483
+ });
2484
+ }
2485
+ if (level === 0) {
2486
+ result.push(current);
2487
+ }
2488
+ parent = arr[level - 1];
2489
+ if (parent) {
2490
+ parent.children.push(current);
2491
+ }
2492
+ arr[level] = current;
2493
+ }
2494
+ if (!isOpen || current.voidElement) {
2495
+ if (level > -1 && (current.voidElement || current.name === tag.slice(2, -1))) {
2496
+ level--;
2497
+ current = level === -1 ? result : arr[level];
2498
+ }
2499
+ if (!inComponent && (nextChar !== '<' || isText) && nextChar) {
2500
+ parent = level === -1 ? result : arr[level].children;
2501
+ const end = nextMatch ? nextMatch.index : -1;
2502
+ let content = html.slice(start, end === -1 ? undefined : end);
2503
+ if (whitespaceRE.test(content)) {
2504
+ content = ' ';
2505
+ }
2506
+ if (end > -1 && level + parent.length >= 0 || content !== ' ') {
2507
+ parent.push({
2508
+ type: 'text',
2509
+ content
2510
+ });
2511
+ }
2512
+ }
2513
+ }
2514
+ });
2515
+ if (restoreNeeded) {
2516
+ restoreSentinels(result);
2517
+ }
2518
+ return result;
2519
+ }
2520
+ function attrString(attrs) {
2521
+ const buff = [];
2522
+ for (const key in attrs) {
2523
+ if (attrs[key] === null) {
2524
+ buff.push(key);
2525
+ } else {
2526
+ buff.push(key + '="' + String(attrs[key]).replace(/"/g, '&quot;') + '"');
2527
+ }
2356
2528
  }
2529
+ if (!buff.length) {
2530
+ return '';
2531
+ }
2532
+ return ' ' + buff.join(' ');
2533
+ }
2534
+ function stringifyNode(buff, doc) {
2535
+ switch (doc.type) {
2536
+ case 'text':
2537
+ return buff + doc.content;
2538
+ case 'tag':
2539
+ {
2540
+ const tagEnd = doc.voidElement && doc.name.toLowerCase() !== '!doctype' ? '/>' : '>';
2541
+ buff += '<' + doc.name + (doc.attrs ? attrString(doc.attrs) : '') + tagEnd;
2542
+ if (doc.voidElement) {
2543
+ return buff;
2544
+ }
2545
+ return buff + doc.children.reduce(stringifyNode, '') + '</' + doc.name + '>';
2546
+ }
2547
+ case 'comment':
2548
+ buff += '<!--' + doc.comment + '-->';
2549
+ return buff;
2550
+ }
2551
+ }
2552
+ function stringify(doc) {
2553
+ return doc.reduce(function (token, rootEl) {
2554
+ return token + stringifyNode('', rootEl);
2555
+ }, '');
2556
+ }
2557
+ var index = {
2558
+ parse,
2559
+ stringify
2357
2560
  };
2358
2561
 
2359
2562
  const warn = (i18n, code, msg, rest) => {
@@ -2571,46 +2774,6 @@
2571
2774
  });
2572
2775
  return stringNode;
2573
2776
  };
2574
- const escapeLiteralLessThan = (str, keepArray = [], knownComponentsMap = {}) => {
2575
- if (!str) return str;
2576
- const knownNames = Object.keys(knownComponentsMap);
2577
- const allValidNames = [...keepArray, ...knownNames];
2578
- let result = '';
2579
- let i = 0;
2580
- while (i < str.length) {
2581
- if (str[i] === '<') {
2582
- let isValidTag = false;
2583
- const closingMatch = str.slice(i).match(/^<\/(\d+|[a-zA-Z][a-zA-Z0-9_-]*)>/);
2584
- if (closingMatch) {
2585
- const tagName = closingMatch[1];
2586
- if (/^\d+$/.test(tagName) || allValidNames.includes(tagName)) {
2587
- isValidTag = true;
2588
- result += closingMatch[0];
2589
- i += closingMatch[0].length;
2590
- }
2591
- }
2592
- if (!isValidTag) {
2593
- const openingMatch = str.slice(i).match(/^<(\d+|[a-zA-Z][a-zA-Z0-9_-]*)(\s+[\w-]+(?:=(?:"[^"]*"|'[^']*'|[^\s>]+))?)*\s*(\/)?>/);
2594
- if (openingMatch) {
2595
- const tagName = openingMatch[1];
2596
- if (/^\d+$/.test(tagName) || allValidNames.includes(tagName)) {
2597
- isValidTag = true;
2598
- result += openingMatch[0];
2599
- i += openingMatch[0].length;
2600
- }
2601
- }
2602
- }
2603
- if (!isValidTag) {
2604
- result += '&lt;';
2605
- i += 1;
2606
- }
2607
- } else {
2608
- result += str[i];
2609
- i += 1;
2610
- }
2611
- }
2612
- return result;
2613
- };
2614
2777
  const renderNodes = (children, knownComponentsMap, targetString, i18n, i18nOptions, combinedTOpts, shouldUnescape) => {
2615
2778
  if (targetString === '') return [];
2616
2779
  const keepArray = i18nOptions.transKeepBasicHtmlNodesFor || [];
@@ -2625,8 +2788,11 @@
2625
2788
  });
2626
2789
  };
2627
2790
  getData(children);
2628
- const escapedString = escapeLiteralLessThan(targetString, keepArray, data);
2629
- const ast = c.parse(`<0>${escapedString}</0>`);
2791
+ const knownNames = Object.keys(data);
2792
+ const allowedTags = name => /^\d+$/.test(name) || keepArray.indexOf(name) > -1 || knownNames.indexOf(name) > -1;
2793
+ const ast = index.parse(`<0>${targetString}</0>`, {
2794
+ allowedTags
2795
+ });
2630
2796
  const opts = {
2631
2797
  ...data,
2632
2798
  ...combinedTOpts
@@ -2831,7 +2997,7 @@
2831
2997
  }) {
2832
2998
  const i18n = i18nFromProps || getI18n();
2833
2999
  if (!i18n) {
2834
- warnOnce(i18n, 'NO_I18NEXT_INSTANCE', `Trans: You need to pass in an i18next instance using i18nextReactModule`, {
3000
+ 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.`, {
2835
3001
  i18nKey
2836
3002
  });
2837
3003
  return children;
@@ -3579,7 +3745,7 @@
3579
3745
  const i18n = i18nFromProps || i18nFromContext || getI18n();
3580
3746
  if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces();
3581
3747
  if (!i18n) {
3582
- warnOnce(i18n, 'NO_I18NEXT_INSTANCE', 'useTranslation: You will need to pass in an i18next instance by using initReactI18next');
3748
+ 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.');
3583
3749
  }
3584
3750
  const i18nOptions = React.useMemo(() => ({
3585
3751
  ...getDefaults(),
@@ -3701,6 +3867,13 @@
3701
3867
  return arr;
3702
3868
  }, [t, finalI18n, ready, finalI18n.resolvedLanguage, finalI18n.language, finalI18n.languages]);
3703
3869
  if (i18n && useSuspense && !ready) {
3870
+ let inDevelopment = false;
3871
+ try {
3872
+ inDevelopment = "development" !== 'production';
3873
+ } catch (e) {}
3874
+ if (inDevelopment) {
3875
+ 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');
3876
+ }
3704
3877
  throw new Promise(resolve => {
3705
3878
  const onLoaded = () => resolve();
3706
3879
  if (props.lng) {