Skip to content

Commit 648c705

Browse files
committed
use modern hasLoadedNamespace code (now requires at least i18next > v19.4.5 (introduced in june 2020))
1 parent 926baf4 commit 648c705

File tree

6 files changed

+53
-49
lines changed

6 files changed

+53
-49
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
### 15.0.0
2+
3+
- use optional chaining, nullish coalescing and nullish coalescing assignment [1774](https://github.com/i18next/react-i18next/pull/1774)
4+
- Build config and optimizations [1769](https://github.com/i18next/react-i18next/pull/1769)
5+
- some dependency updates [1768](https://github.com/i18next/react-i18next/pull/1768)
6+
- use modern hasLoadedNamespace code (now requires at least i18next > v19.4.5 (introduced in june 2020))
7+
18
### 14.1.3
29

310
- create a isObject helper function [1766](https://github.com/i18next/react-i18next/pull/1766)

src/utils.js

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -51,61 +51,12 @@ export const loadLanguages = (i18n, lng, ns, cb) => {
5151
i18n.loadLanguages(lng, loadedClb(i18n, cb));
5252
};
5353

54-
// WAIT A LITTLE FOR I18NEXT BEING UPDATED IN THE WILD, before removing this old i18next version support
55-
const oldI18nextHasLoadedNamespace = (ns, i18n, options = {}) => {
56-
const lng = i18n.languages[0];
57-
const fallbackLng = i18n.options?.fallbackLng ?? false;
58-
const lastLng = i18n.languages[i18n.languages.length - 1];
59-
60-
// we're in cimode so this shall pass
61-
if (lng.toLowerCase() === 'cimode') return true;
62-
63-
const loadNotPending = (l, n) => {
64-
const loadState = i18n.services.backendConnector.state[`${l}|${n}`];
65-
return loadState === -1 || loadState === 2;
66-
};
67-
68-
// bound to trigger on event languageChanging
69-
// so set ready to false while we are changing the language
70-
// and namespace pending (depends on having a backend)
71-
if (
72-
options.bindI18n?.indexOf('languageChanging') > -1 &&
73-
i18n.services.backendConnector.backend &&
74-
i18n.isLanguageChangingTo &&
75-
!loadNotPending(i18n.isLanguageChangingTo, ns)
76-
)
77-
return false;
78-
79-
// loaded -> SUCCESS
80-
if (i18n.hasResourceBundle(lng, ns)) return true;
81-
82-
// were not loading at all -> SEMI SUCCESS
83-
if (
84-
!i18n.services.backendConnector.backend ||
85-
(i18n.options.resources && !i18n.options.partialBundledLanguages)
86-
)
87-
return true;
88-
89-
// failed loading ns - but at least fallback is not pending -> SEMI SUCCESS
90-
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
91-
92-
return false;
93-
};
94-
9554
export const hasLoadedNamespace = (ns, i18n, options = {}) => {
9655
if (!i18n.languages || !i18n.languages.length) {
9756
warnOnce('i18n.languages were undefined or empty', i18n.languages);
9857
return true;
9958
}
10059

101-
// ignoreJSONStructure was introduced in v20.0.0 (MARCH 2021)
102-
const isNewerI18next = i18n.options.ignoreJSONStructure !== undefined;
103-
if (!isNewerI18next) {
104-
// WAIT A LITTLE FOR I18NEXT BEING UPDATED IN THE WILD, before removing this old i18next version support
105-
return oldI18nextHasLoadedNamespace(ns, i18n, options);
106-
}
107-
108-
// IN I18NEXT > v19.4.5 WE CAN (INTRODUCED JUNE 2020)
10960
return i18n.hasLoadedNamespace(ns, {
11061
lng: options.lng,
11162
precheck: (i18nInstance, loadNotPending) => {

test/I18nextProvider.spec.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import { render, screen, cleanup } from '@testing-library/react';
44
import { I18nextProvider } from '../src/I18nextProvider';
55
import { useTranslation } from '../src/useTranslation';
6+
import hasLoadedNamespace from './hasLoadedNamespaceMock.js';
67

78
vitest.unmock('../src/useTranslation');
89
vitest.unmock('../src/I18nextProvider');
@@ -21,6 +22,7 @@ const instance = {
2122
getFixedT: () => (message) => message,
2223
hasResourceBundle: (lng, ns) => ns === 'translation',
2324
loadNamespaces: () => {},
25+
hasLoadedNamespace: (ns) => hasLoadedNamespace(ns, instance),
2426
on: () => {},
2527
off: () => {},
2628
options: {},

test/hasLoadedNamespaceMock.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
export default (ns, i18n, options = {}) => {
2+
const lng = i18n.languages[0];
3+
const fallbackLng = i18n.options ? i18n.options.fallbackLng : false;
4+
const lastLng = i18n.languages[i18n.languages.length - 1];
5+
6+
// we're in cimode so this shall pass
7+
if (lng.toLowerCase() === 'cimode') return true;
8+
9+
const loadNotPending = (l, n) => {
10+
const loadState = i18n.services.backendConnector.state[`${l}|${n}`];
11+
return loadState === -1 || loadState === 2;
12+
};
13+
14+
// bound to trigger on event languageChanging
15+
// so set ready to false while we are changing the language
16+
// and namespace pending (depends on having a backend)
17+
if (
18+
options.bindI18n &&
19+
options.bindI18n.indexOf('languageChanging') > -1 &&
20+
i18n.services.backendConnector.backend &&
21+
i18n.isLanguageChangingTo &&
22+
!loadNotPending(i18n.isLanguageChangingTo, ns)
23+
)
24+
return false;
25+
26+
// loaded -> SUCCESS
27+
if (i18n.hasResourceBundle(lng, ns)) return true;
28+
29+
// were not loading at all -> SEMI SUCCESS
30+
if (
31+
!i18n.services.backendConnector.backend ||
32+
(i18n.options.resources && !i18n.options.partialBundledLanguages)
33+
)
34+
return true;
35+
36+
// failed loading ns - but at least fallback is not pending -> SEMI SUCCESS
37+
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
38+
39+
return false;
40+
};

test/useTranslation.ready.spec.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import { renderHook, cleanup as cleanupHook } from '@testing-library/react-hooks';
44
import { render, cleanup } from '@testing-library/react';
55
import { useTranslation } from '../src/useTranslation';
6+
import hasLoadedNamespace from './hasLoadedNamespaceMock.js';
67

78
vitest.unmock('../src/useTranslation');
89

@@ -28,6 +29,7 @@ afterEach(() => {
2829
getFixedT: () => (message) => message,
2930
hasResourceBundle: (lng, ns) => ns === 'alreadyLoadedNS',
3031
loadNamespaces: () => {},
32+
hasLoadedNamespace: (ns) => hasLoadedNamespace(ns, instance),
3133
on: () => {},
3234
off: () => {},
3335
options: {},

test/withSSR.spec.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import i18n from './i18n';
55
import { setI18n } from '../src/context';
66
import { withSSR } from '../src/withSSR';
77
import { useTranslation } from '../src/useTranslation';
8+
import hasLoadedNamespace from './hasLoadedNamespaceMock.js';
89

910
vitest.unmock('../src/withSSR');
1011

@@ -36,6 +37,7 @@ describe('withSSR', () => {
3637
hasResourceBundle: (lng, ns) => ns === 'alreadyLoadedNS',
3738
getResourceBundle: (lng, ns) => ({ lng, ns }),
3839
loadNamespaces: () => { },
40+
hasLoadedNamespace: (ns) => hasLoadedNamespace(ns, mockI18n),
3941
on: () => { },
4042
off: () => { },
4143
};

0 commit comments

Comments
 (0)