willba-component-library 0.3.27 → 0.4.0
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/README.md +75 -113
- package/lib/components/FilterBar/FilterBar.d.ts +1 -1
- package/lib/components/FilterCalendar/FilterCalendar.d.ts +1 -1
- package/lib/core/i18n/I18nProvider.d.ts +6 -0
- package/lib/core/i18n/index.d.ts +1 -0
- package/lib/embed.d.ts +18 -0
- package/lib/embed.esm.js +74 -0
- package/lib/embed.esm.js.map +1 -0
- package/lib/embed.umd.js +74 -0
- package/lib/embed.umd.js.map +1 -0
- package/lib/i18n.d.ts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.esm.js +1111 -930
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1110 -929
- package/lib/index.js.map +1 -1
- package/package.json +9 -1
- package/.nvmrc +0 -1
- package/.storybook/main.ts +0 -17
- package/.storybook/preview.ts +0 -15
- package/lib/components/FilterBar/components/buttons/index.d.ts +0 -4
- package/lib/components/FilterBar/components/buttons/select-button/SelectButton.d.ts +0 -13
- package/lib/components/FilterBar/components/buttons/tab-button/TabButton.d.ts +0 -10
- package/lib/components/FilterBar/components/cards/image-card/ImageCard.d.ts +0 -11
- package/lib/components/FilterBar/components/cards/index.d.ts +0 -1
- package/lib/components/FilterBar/components/categories/Categories.d.ts +0 -8
- package/lib/components/FilterBar/components/common/FilterSectionHeader.d.ts +0 -8
- package/lib/components/FilterBar/components/dates/Dates.d.ts +0 -17
- package/lib/components/FilterBar/components/dates/index.d.ts +0 -1
- package/lib/components/FilterBar/components/guests/GuestCount/GuestCount.d.ts +0 -4
- package/lib/components/FilterBar/components/guests/Guests.d.ts +0 -12
- package/lib/components/FilterBar/components/locations/Locations.d.ts +0 -14
- package/lib/components/FilterBar/hooks/useFilterBar.d.ts +0 -32
- package/lib/components/FilterBar/hooks/useFilterUi.d.ts +0 -8
- package/lib/components/FilterBar/utils/calculateDropdownPosition.d.ts +0 -12
- package/lib/components/FilterBar/utils/getLocalizedContent.d.ts +0 -8
- package/lib/core/components/buttons/close-button/CloseButton.d.ts +0 -7
- package/lib/core/components/buttons/submit-button/SubmitButton.d.ts +0 -14
- package/lib/index.umd.js +0 -12489
- package/lib/index.umd.js.map +0 -1
- package/prettier.config.js +0 -6
- package/rollup.config.mjs +0 -63
- package/src/assets/IconsSvg.tsx +0 -69
- package/src/components/Button/Button.stories.tsx +0 -34
- package/src/components/Button/Button.tsx +0 -56
- package/src/components/Button/button.css +0 -30
- package/src/components/Button/index.ts +0 -1
- package/src/components/FilterBar/FilterBar.css +0 -35
- package/src/components/FilterBar/FilterBar.stories.tsx +0 -116
- package/src/components/FilterBar/FilterBar.tsx +0 -64
- package/src/components/FilterBar/FilterBarTypes.ts +0 -71
- package/src/components/FilterBar/components/Divider/Divider.css +0 -14
- package/src/components/FilterBar/components/Divider/Divider.tsx +0 -7
- package/src/components/FilterBar/components/FilterControls/FilterControls.css +0 -22
- package/src/components/FilterBar/components/FilterControls/FilterControls.tsx +0 -139
- package/src/components/FilterBar/components/FilterPanels/Categories/Categories.css +0 -21
- package/src/components/FilterBar/components/FilterPanels/Categories/Categories.tsx +0 -49
- package/src/components/FilterBar/components/FilterPanels/Dates/Dates.css +0 -9
- package/src/components/FilterBar/components/FilterPanels/Dates/Dates.tsx +0 -60
- package/src/components/FilterBar/components/FilterPanels/FilterPanels.css +0 -22
- package/src/components/FilterBar/components/FilterPanels/FilterPanels.tsx +0 -111
- package/src/components/FilterBar/components/FilterPanels/Guests/GuestCount/GuestCount.css +0 -58
- package/src/components/FilterBar/components/FilterPanels/Guests/GuestCount/GuestCount.tsx +0 -85
- package/src/components/FilterBar/components/FilterPanels/Guests/Guests.css +0 -24
- package/src/components/FilterBar/components/FilterPanels/Guests/Guests.tsx +0 -59
- package/src/components/FilterBar/components/FilterPanels/Locations/Locations.css +0 -16
- package/src/components/FilterBar/components/FilterPanels/Locations/Locations.tsx +0 -94
- package/src/components/FilterBar/components/FilterPanels/SectionHeader/SectionHeader.css +0 -34
- package/src/components/FilterBar/components/FilterPanels/SectionHeader/SectionHeader.tsx +0 -17
- package/src/components/FilterBar/components/FilterTabs/FilterTabs.css +0 -10
- package/src/components/FilterBar/components/FilterTabs/FilterTabs.tsx +0 -50
- package/src/components/FilterBar/components/ImageCard/ImageCard.css +0 -30
- package/src/components/FilterBar/components/ImageCard/ImageCard.tsx +0 -45
- package/src/components/FilterBar/components/SelectButton/SelectButton.css +0 -76
- package/src/components/FilterBar/components/SelectButton/SelectButton.tsx +0 -54
- package/src/components/FilterBar/components/TabButton/TabButton.css +0 -36
- package/src/components/FilterBar/components/TabButton/TabButton.tsx +0 -23
- package/src/components/FilterBar/components/index.ts +0 -6
- package/src/components/FilterBar/hooks/index.ts +0 -5
- package/src/components/FilterBar/hooks/useFilterActions.tsx +0 -126
- package/src/components/FilterBar/hooks/useFilterRefs.tsx +0 -21
- package/src/components/FilterBar/hooks/useFilterState.tsx +0 -86
- package/src/components/FilterBar/hooks/usePanelPosition.tsx +0 -52
- package/src/components/FilterBar/hooks/useScrollInToView.tsx +0 -29
- package/src/components/FilterBar/index.ts +0 -3
- package/src/components/FilterBar/providers/FilterBarProvider.tsx +0 -172
- package/src/components/FilterBar/providers/index.ts +0 -1
- package/src/components/FilterBar/utils/ageCategoriesRules.ts +0 -27
- package/src/components/FilterBar/utils/index.tsx +0 -3
- package/src/components/FilterBar/utils/parseGuests.tsx +0 -65
- package/src/components/FilterBar/utils/parseLocations.ts +0 -28
- package/src/components/FilterCalendar/FilterCalendar.css +0 -109
- package/src/components/FilterCalendar/FilterCalendar.stories.tsx +0 -554
- package/src/components/FilterCalendar/FilterCalendar.tsx +0 -115
- package/src/components/FilterCalendar/FilterCalendarTypes.ts +0 -11
- package/src/components/FilterCalendar/components/Footer.tsx +0 -96
- package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +0 -163
- package/src/components/FilterCalendar/index.ts +0 -3
- package/src/core/components/buttons/CloseButton/CloseButton.css +0 -33
- package/src/core/components/buttons/CloseButton/CloseButton.tsx +0 -16
- package/src/core/components/buttons/SubmitButton/SubmitButton.css +0 -54
- package/src/core/components/buttons/SubmitButton/SubmitButton.tsx +0 -42
- package/src/core/components/calendar/Calendar.css +0 -280
- package/src/core/components/calendar/Calendar.tsx +0 -253
- package/src/core/components/calendar/CalendarTypes.ts +0 -48
- package/src/core/components/calendar/hooks/index.ts +0 -3
- package/src/core/components/calendar/hooks/useCalendarLoadingSpinner.tsx +0 -19
- package/src/core/components/calendar/hooks/useCalendarTooltips.tsx +0 -125
- package/src/core/components/calendar/hooks/useUpdateDisabledDates.tsx +0 -105
- package/src/core/components/calendar/utils/calendarSelectionRules.tsx +0 -180
- package/src/core/components/calendar/utils/checkForContinuousSelection.tsx +0 -86
- package/src/core/components/calendar/utils/disabledDatesByPage.tsx +0 -31
- package/src/core/components/calendar/utils/handleCalendarModifiers.tsx +0 -118
- package/src/core/components/calendar/utils/handleRangeContextDisabledDates.tsx +0 -75
- package/src/core/components/calendar/utils/index.ts +0 -8
- package/src/core/components/calendar/utils/nightsCount.tsx +0 -19
- package/src/core/components/calendar/utils/parseDate.tsx +0 -17
- package/src/core/components/calendar/utils/parseDates.tsx +0 -12
- package/src/core/components/index.ts +0 -7
- package/src/core/hooks/index.ts +0 -4
- package/src/core/hooks/useAutoFocus.tsx +0 -27
- package/src/core/hooks/useAwaitRender.tsx +0 -12
- package/src/core/hooks/useCloseFilterSection.tsx +0 -29
- package/src/core/hooks/useUpdateTranslations.tsx +0 -14
- package/src/i18n.ts +0 -27
- package/src/index.ts +0 -8
- package/src/locales/en/common.json +0 -18
- package/src/locales/en/filterBar.json +0 -33
- package/src/locales/fi/common.json +0 -19
- package/src/locales/fi/filterBar.json +0 -33
- package/src/themes/Default.css +0 -69
- package/src/themes/useTheme.tsx +0 -27
- package/stories/Button.stories.ts +0 -50
- package/stories/Button.tsx +0 -53
- package/stories/Configure.mdx +0 -364
- package/stories/Header.stories.ts +0 -27
- package/stories/Header.tsx +0 -70
- package/stories/Page.stories.ts +0 -29
- package/stories/Page.tsx +0 -91
- package/stories/assets/accessibility.png +0 -0
- package/stories/assets/accessibility.svg +0 -5
- package/stories/assets/addon-library.png +0 -0
- package/stories/assets/assets.png +0 -0
- package/stories/assets/context.png +0 -0
- package/stories/assets/discord.svg +0 -15
- package/stories/assets/docs.png +0 -0
- package/stories/assets/figma-plugin.png +0 -0
- package/stories/assets/github.svg +0 -3
- package/stories/assets/share.png +0 -0
- package/stories/assets/styling.png +0 -0
- package/stories/assets/testing.png +0 -0
- package/stories/assets/theming.png +0 -0
- package/stories/assets/tutorials.svg +0 -12
- package/stories/assets/youtube.svg +0 -4
- package/stories/button.css +0 -30
- package/stories/header.css +0 -32
- package/stories/page.css +0 -69
- package/tsconfig.json +0 -29
- /package/lib/components/FilterBar/components/{divider → Divider}/Divider.d.ts +0 -0
package/lib/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import React__default, { useState, useEffect, createContext, useContext, useRef, forwardRef, useLayoutEffect
|
|
2
|
+
import React__default, { useState, useEffect, createContext, useContext, useRef, useMemo, createElement, forwardRef, useLayoutEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
/******************************************************************************
|
|
5
5
|
Copyright (c) Microsoft Corporation.
|
|
@@ -222,6 +222,331 @@ var useAwaitRender = function () {
|
|
|
222
222
|
return null;
|
|
223
223
|
};
|
|
224
224
|
|
|
225
|
+
function warn() {
|
|
226
|
+
if (console && console.warn) {
|
|
227
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
228
|
+
args[_key] = arguments[_key];
|
|
229
|
+
}
|
|
230
|
+
if (typeof args[0] === 'string') args[0] = `react-i18next:: ${args[0]}`;
|
|
231
|
+
console.warn(...args);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const alreadyWarned = {};
|
|
235
|
+
function warnOnce() {
|
|
236
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
237
|
+
args[_key2] = arguments[_key2];
|
|
238
|
+
}
|
|
239
|
+
if (typeof args[0] === 'string' && alreadyWarned[args[0]]) return;
|
|
240
|
+
if (typeof args[0] === 'string') alreadyWarned[args[0]] = new Date();
|
|
241
|
+
warn(...args);
|
|
242
|
+
}
|
|
243
|
+
const loadedClb = (i18n, cb) => () => {
|
|
244
|
+
if (i18n.isInitialized) {
|
|
245
|
+
cb();
|
|
246
|
+
} else {
|
|
247
|
+
const initialized = () => {
|
|
248
|
+
setTimeout(() => {
|
|
249
|
+
i18n.off('initialized', initialized);
|
|
250
|
+
}, 0);
|
|
251
|
+
cb();
|
|
252
|
+
};
|
|
253
|
+
i18n.on('initialized', initialized);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
function loadNamespaces(i18n, ns, cb) {
|
|
257
|
+
i18n.loadNamespaces(ns, loadedClb(i18n, cb));
|
|
258
|
+
}
|
|
259
|
+
function loadLanguages(i18n, lng, ns, cb) {
|
|
260
|
+
if (typeof ns === 'string') ns = [ns];
|
|
261
|
+
ns.forEach(n => {
|
|
262
|
+
if (i18n.options.ns.indexOf(n) < 0) i18n.options.ns.push(n);
|
|
263
|
+
});
|
|
264
|
+
i18n.loadLanguages(lng, loadedClb(i18n, cb));
|
|
265
|
+
}
|
|
266
|
+
function oldI18nextHasLoadedNamespace(ns, i18n) {
|
|
267
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
268
|
+
const lng = i18n.languages[0];
|
|
269
|
+
const fallbackLng = i18n.options ? i18n.options.fallbackLng : false;
|
|
270
|
+
const lastLng = i18n.languages[i18n.languages.length - 1];
|
|
271
|
+
if (lng.toLowerCase() === 'cimode') return true;
|
|
272
|
+
const loadNotPending = (l, n) => {
|
|
273
|
+
const loadState = i18n.services.backendConnector.state[`${l}|${n}`];
|
|
274
|
+
return loadState === -1 || loadState === 2;
|
|
275
|
+
};
|
|
276
|
+
if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18n.services.backendConnector.backend && i18n.isLanguageChangingTo && !loadNotPending(i18n.isLanguageChangingTo, ns)) return false;
|
|
277
|
+
if (i18n.hasResourceBundle(lng, ns)) return true;
|
|
278
|
+
if (!i18n.services.backendConnector.backend || i18n.options.resources && !i18n.options.partialBundledLanguages) return true;
|
|
279
|
+
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
function hasLoadedNamespace(ns, i18n) {
|
|
283
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
284
|
+
if (!i18n.languages || !i18n.languages.length) {
|
|
285
|
+
warnOnce('i18n.languages were undefined or empty', i18n.languages);
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
const isNewerI18next = i18n.options.ignoreJSONStructure !== undefined;
|
|
289
|
+
if (!isNewerI18next) {
|
|
290
|
+
return oldI18nextHasLoadedNamespace(ns, i18n, options);
|
|
291
|
+
}
|
|
292
|
+
return i18n.hasLoadedNamespace(ns, {
|
|
293
|
+
lng: options.lng,
|
|
294
|
+
precheck: (i18nInstance, loadNotPending) => {
|
|
295
|
+
if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18nInstance.services.backendConnector.backend && i18nInstance.isLanguageChangingTo && !loadNotPending(i18nInstance.isLanguageChangingTo, ns)) return false;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const matchHtmlEntity = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g;
|
|
301
|
+
const htmlEntities = {
|
|
302
|
+
'&': '&',
|
|
303
|
+
'&': '&',
|
|
304
|
+
'<': '<',
|
|
305
|
+
'<': '<',
|
|
306
|
+
'>': '>',
|
|
307
|
+
'>': '>',
|
|
308
|
+
''': "'",
|
|
309
|
+
''': "'",
|
|
310
|
+
'"': '"',
|
|
311
|
+
'"': '"',
|
|
312
|
+
' ': ' ',
|
|
313
|
+
' ': ' ',
|
|
314
|
+
'©': '©',
|
|
315
|
+
'©': '©',
|
|
316
|
+
'®': '®',
|
|
317
|
+
'®': '®',
|
|
318
|
+
'…': '…',
|
|
319
|
+
'…': '…',
|
|
320
|
+
'/': '/',
|
|
321
|
+
'/': '/'
|
|
322
|
+
};
|
|
323
|
+
const unescapeHtmlEntity = m => htmlEntities[m];
|
|
324
|
+
const unescape = text => text.replace(matchHtmlEntity, unescapeHtmlEntity);
|
|
325
|
+
|
|
326
|
+
let defaultOptions$1 = {
|
|
327
|
+
bindI18n: 'languageChanged',
|
|
328
|
+
bindI18nStore: '',
|
|
329
|
+
transEmptyNodeValue: '',
|
|
330
|
+
transSupportBasicHtmlNodes: true,
|
|
331
|
+
transWrapTextNodes: '',
|
|
332
|
+
transKeepBasicHtmlNodesFor: ['br', 'strong', 'i', 'p'],
|
|
333
|
+
useSuspense: true,
|
|
334
|
+
unescape
|
|
335
|
+
};
|
|
336
|
+
function setDefaults() {
|
|
337
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
338
|
+
defaultOptions$1 = {
|
|
339
|
+
...defaultOptions$1,
|
|
340
|
+
...options
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
function getDefaults() {
|
|
344
|
+
return defaultOptions$1;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
let i18nInstance;
|
|
348
|
+
function setI18n(instance) {
|
|
349
|
+
i18nInstance = instance;
|
|
350
|
+
}
|
|
351
|
+
function getI18n() {
|
|
352
|
+
return i18nInstance;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const initReactI18next = {
|
|
356
|
+
type: '3rdParty',
|
|
357
|
+
init(instance) {
|
|
358
|
+
setDefaults(instance.options.react);
|
|
359
|
+
setI18n(instance);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const I18nContext = createContext();
|
|
364
|
+
class ReportNamespaces {
|
|
365
|
+
constructor() {
|
|
366
|
+
this.usedNamespaces = {};
|
|
367
|
+
}
|
|
368
|
+
addUsedNamespaces(namespaces) {
|
|
369
|
+
namespaces.forEach(ns => {
|
|
370
|
+
if (!this.usedNamespaces[ns]) this.usedNamespaces[ns] = true;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
getUsedNamespaces() {
|
|
374
|
+
return Object.keys(this.usedNamespaces);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const usePrevious = (value, ignore) => {
|
|
379
|
+
const ref = useRef();
|
|
380
|
+
useEffect(() => {
|
|
381
|
+
ref.current = ignore ? ref.current : value;
|
|
382
|
+
}, [value, ignore]);
|
|
383
|
+
return ref.current;
|
|
384
|
+
};
|
|
385
|
+
function useTranslation(ns) {
|
|
386
|
+
let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
387
|
+
const {
|
|
388
|
+
i18n: i18nFromProps
|
|
389
|
+
} = props;
|
|
390
|
+
const {
|
|
391
|
+
i18n: i18nFromContext,
|
|
392
|
+
defaultNS: defaultNSFromContext
|
|
393
|
+
} = useContext(I18nContext) || {};
|
|
394
|
+
const i18n = i18nFromProps || i18nFromContext || getI18n();
|
|
395
|
+
if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces();
|
|
396
|
+
if (!i18n) {
|
|
397
|
+
warnOnce('You will need to pass in an i18next instance by using initReactI18next');
|
|
398
|
+
const notReadyT = (k, optsOrDefaultValue) => {
|
|
399
|
+
if (typeof optsOrDefaultValue === 'string') return optsOrDefaultValue;
|
|
400
|
+
if (optsOrDefaultValue && typeof optsOrDefaultValue === 'object' && typeof optsOrDefaultValue.defaultValue === 'string') return optsOrDefaultValue.defaultValue;
|
|
401
|
+
return Array.isArray(k) ? k[k.length - 1] : k;
|
|
402
|
+
};
|
|
403
|
+
const retNotReady = [notReadyT, {}, false];
|
|
404
|
+
retNotReady.t = notReadyT;
|
|
405
|
+
retNotReady.i18n = {};
|
|
406
|
+
retNotReady.ready = false;
|
|
407
|
+
return retNotReady;
|
|
408
|
+
}
|
|
409
|
+
if (i18n.options.react && i18n.options.react.wait !== undefined) warnOnce('It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.');
|
|
410
|
+
const i18nOptions = {
|
|
411
|
+
...getDefaults(),
|
|
412
|
+
...i18n.options.react,
|
|
413
|
+
...props
|
|
414
|
+
};
|
|
415
|
+
const {
|
|
416
|
+
useSuspense,
|
|
417
|
+
keyPrefix
|
|
418
|
+
} = i18nOptions;
|
|
419
|
+
let namespaces = ns || defaultNSFromContext || i18n.options && i18n.options.defaultNS;
|
|
420
|
+
namespaces = typeof namespaces === 'string' ? [namespaces] : namespaces || ['translation'];
|
|
421
|
+
if (i18n.reportNamespaces.addUsedNamespaces) i18n.reportNamespaces.addUsedNamespaces(namespaces);
|
|
422
|
+
const ready = (i18n.isInitialized || i18n.initializedStoreOnce) && namespaces.every(n => hasLoadedNamespace(n, i18n, i18nOptions));
|
|
423
|
+
function getT() {
|
|
424
|
+
return i18n.getFixedT(props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix);
|
|
425
|
+
}
|
|
426
|
+
const [t, setT] = useState(getT);
|
|
427
|
+
let joinedNS = namespaces.join();
|
|
428
|
+
if (props.lng) joinedNS = `${props.lng}${joinedNS}`;
|
|
429
|
+
const previousJoinedNS = usePrevious(joinedNS);
|
|
430
|
+
const isMounted = useRef(true);
|
|
431
|
+
useEffect(() => {
|
|
432
|
+
const {
|
|
433
|
+
bindI18n,
|
|
434
|
+
bindI18nStore
|
|
435
|
+
} = i18nOptions;
|
|
436
|
+
isMounted.current = true;
|
|
437
|
+
if (!ready && !useSuspense) {
|
|
438
|
+
if (props.lng) {
|
|
439
|
+
loadLanguages(i18n, props.lng, namespaces, () => {
|
|
440
|
+
if (isMounted.current) setT(getT);
|
|
441
|
+
});
|
|
442
|
+
} else {
|
|
443
|
+
loadNamespaces(i18n, namespaces, () => {
|
|
444
|
+
if (isMounted.current) setT(getT);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (ready && previousJoinedNS && previousJoinedNS !== joinedNS && isMounted.current) {
|
|
449
|
+
setT(getT);
|
|
450
|
+
}
|
|
451
|
+
function boundReset() {
|
|
452
|
+
if (isMounted.current) setT(getT);
|
|
453
|
+
}
|
|
454
|
+
if (bindI18n && i18n) i18n.on(bindI18n, boundReset);
|
|
455
|
+
if (bindI18nStore && i18n) i18n.store.on(bindI18nStore, boundReset);
|
|
456
|
+
return () => {
|
|
457
|
+
isMounted.current = false;
|
|
458
|
+
if (bindI18n && i18n) bindI18n.split(' ').forEach(e => i18n.off(e, boundReset));
|
|
459
|
+
if (bindI18nStore && i18n) bindI18nStore.split(' ').forEach(e => i18n.store.off(e, boundReset));
|
|
460
|
+
};
|
|
461
|
+
}, [i18n, joinedNS]);
|
|
462
|
+
const isInitial = useRef(true);
|
|
463
|
+
useEffect(() => {
|
|
464
|
+
if (isMounted.current && !isInitial.current) {
|
|
465
|
+
setT(getT);
|
|
466
|
+
}
|
|
467
|
+
isInitial.current = false;
|
|
468
|
+
}, [i18n, keyPrefix]);
|
|
469
|
+
const ret = [t, i18n, ready];
|
|
470
|
+
ret.t = t;
|
|
471
|
+
ret.i18n = i18n;
|
|
472
|
+
ret.ready = ready;
|
|
473
|
+
if (ready) return ret;
|
|
474
|
+
if (!ready && !useSuspense) return ret;
|
|
475
|
+
throw new Promise(resolve => {
|
|
476
|
+
if (props.lng) {
|
|
477
|
+
loadLanguages(i18n, props.lng, namespaces, () => resolve());
|
|
478
|
+
} else {
|
|
479
|
+
loadNamespaces(i18n, namespaces, () => resolve());
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function I18nextProvider(_ref) {
|
|
485
|
+
let {
|
|
486
|
+
i18n,
|
|
487
|
+
defaultNS,
|
|
488
|
+
children
|
|
489
|
+
} = _ref;
|
|
490
|
+
const value = useMemo(() => ({
|
|
491
|
+
i18n,
|
|
492
|
+
defaultNS
|
|
493
|
+
}), [i18n, defaultNS]);
|
|
494
|
+
return createElement(I18nContext.Provider, {
|
|
495
|
+
value
|
|
496
|
+
}, children);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
var useUpdateTranslations = function (_a) {
|
|
500
|
+
var language = _a.language;
|
|
501
|
+
var i18n = useTranslation().i18n;
|
|
502
|
+
useEffect(function () {
|
|
503
|
+
if (language && i18n.language !== language) {
|
|
504
|
+
i18n.changeLanguage(language);
|
|
505
|
+
}
|
|
506
|
+
}, [language, i18n]);
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
// TODO - Refactor and rename this hook
|
|
510
|
+
var useCloseFilterSection = function (_a) {
|
|
511
|
+
var handleSelectedFilter = _a.handleSelectedFilter;
|
|
512
|
+
var filterSectionRef = useRef(null);
|
|
513
|
+
useEffect(function () {
|
|
514
|
+
var handleClickOutside = function (event) {
|
|
515
|
+
if (filterSectionRef.current &&
|
|
516
|
+
!filterSectionRef.current.contains(event.target)) {
|
|
517
|
+
handleSelectedFilter(false);
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
521
|
+
return function () {
|
|
522
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
523
|
+
};
|
|
524
|
+
}, [filterSectionRef]);
|
|
525
|
+
return { filterSectionRef: filterSectionRef };
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
var useAutoFocus = function (autoFocus) {
|
|
529
|
+
var ref = useRef(null);
|
|
530
|
+
useEffect(function () {
|
|
531
|
+
if (!autoFocus || !ref.current)
|
|
532
|
+
return;
|
|
533
|
+
var attemptFocus = function (attempts) {
|
|
534
|
+
if (attempts === void 0) { attempts = 0; }
|
|
535
|
+
if (attempts > 20 || !ref.current)
|
|
536
|
+
return;
|
|
537
|
+
var focusable = ref.current.querySelector('button:not([disabled]), [tabindex]:not([tabindex="-1"])');
|
|
538
|
+
if (focusable) {
|
|
539
|
+
focusable.focus();
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
requestAnimationFrame(function () { return attemptFocus(attempts + 1); });
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
requestAnimationFrame(function () { return attemptFocus(); });
|
|
546
|
+
}, [autoFocus]);
|
|
547
|
+
return ref;
|
|
548
|
+
};
|
|
549
|
+
|
|
225
550
|
const isString = obj => typeof obj === 'string';
|
|
226
551
|
const defer = () => {
|
|
227
552
|
let res;
|
|
@@ -282,7 +607,7 @@ const setPath = (object, path, newValue) => {
|
|
|
282
607
|
e = `${p[p.length - 1]}.${e}`;
|
|
283
608
|
p = p.slice(0, p.length - 1);
|
|
284
609
|
last = getLastOfPath(object, p, Object);
|
|
285
|
-
if (last
|
|
610
|
+
if (last && last.obj && typeof last.obj[`${last.k}.${e}`] !== 'undefined') {
|
|
286
611
|
last.obj = undefined;
|
|
287
612
|
}
|
|
288
613
|
}
|
|
@@ -302,7 +627,6 @@ const getPath = (object, path) => {
|
|
|
302
627
|
k
|
|
303
628
|
} = getLastOfPath(object, path);
|
|
304
629
|
if (!obj) return undefined;
|
|
305
|
-
if (!Object.prototype.hasOwnProperty.call(obj, k)) return undefined;
|
|
306
630
|
return obj[k];
|
|
307
631
|
};
|
|
308
632
|
const getPathWithDefaults = (data, defaultData, key) => {
|
|
@@ -380,12 +704,10 @@ const looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
|
|
|
380
704
|
}
|
|
381
705
|
return matched;
|
|
382
706
|
};
|
|
383
|
-
const deepFind = (obj, path
|
|
707
|
+
const deepFind = function (obj, path) {
|
|
708
|
+
let keySeparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '.';
|
|
384
709
|
if (!obj) return undefined;
|
|
385
|
-
if (obj[path])
|
|
386
|
-
if (!Object.prototype.hasOwnProperty.call(obj, path)) return undefined;
|
|
387
|
-
return obj[path];
|
|
388
|
-
}
|
|
710
|
+
if (obj[path]) return obj[path];
|
|
389
711
|
const tokens = path.split(keySeparator);
|
|
390
712
|
let current = obj;
|
|
391
713
|
for (let i = 0; i < tokens.length;) {
|
|
@@ -412,7 +734,7 @@ const deepFind = (obj, path, keySeparator = '.') => {
|
|
|
412
734
|
}
|
|
413
735
|
return current;
|
|
414
736
|
};
|
|
415
|
-
const getCleanedCode = code => code
|
|
737
|
+
const getCleanedCode = code => code && code.replace('_', '-');
|
|
416
738
|
|
|
417
739
|
const consoleLogger = {
|
|
418
740
|
type: 'logger',
|
|
@@ -426,29 +748,43 @@ const consoleLogger = {
|
|
|
426
748
|
this.output('error', args);
|
|
427
749
|
},
|
|
428
750
|
output(type, args) {
|
|
429
|
-
console
|
|
751
|
+
if (console && console[type]) console[type].apply(console, args);
|
|
430
752
|
}
|
|
431
753
|
};
|
|
432
754
|
class Logger {
|
|
433
|
-
constructor(concreteLogger
|
|
755
|
+
constructor(concreteLogger) {
|
|
756
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
434
757
|
this.init(concreteLogger, options);
|
|
435
758
|
}
|
|
436
|
-
init(concreteLogger
|
|
759
|
+
init(concreteLogger) {
|
|
760
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
437
761
|
this.prefix = options.prefix || 'i18next:';
|
|
438
762
|
this.logger = concreteLogger || consoleLogger;
|
|
439
763
|
this.options = options;
|
|
440
764
|
this.debug = options.debug;
|
|
441
765
|
}
|
|
442
|
-
log(
|
|
766
|
+
log() {
|
|
767
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
768
|
+
args[_key] = arguments[_key];
|
|
769
|
+
}
|
|
443
770
|
return this.forward(args, 'log', '', true);
|
|
444
771
|
}
|
|
445
|
-
warn(
|
|
772
|
+
warn() {
|
|
773
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
774
|
+
args[_key2] = arguments[_key2];
|
|
775
|
+
}
|
|
446
776
|
return this.forward(args, 'warn', '', true);
|
|
447
777
|
}
|
|
448
|
-
error(
|
|
778
|
+
error() {
|
|
779
|
+
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
780
|
+
args[_key3] = arguments[_key3];
|
|
781
|
+
}
|
|
449
782
|
return this.forward(args, 'error', '');
|
|
450
783
|
}
|
|
451
|
-
deprecate(
|
|
784
|
+
deprecate() {
|
|
785
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
786
|
+
args[_key4] = arguments[_key4];
|
|
787
|
+
}
|
|
452
788
|
return this.forward(args, 'warn', 'WARNING DEPRECATED: ', true);
|
|
453
789
|
}
|
|
454
790
|
forward(args, lvl, prefix, debugOnly) {
|
|
@@ -492,10 +828,14 @@ class EventEmitter {
|
|
|
492
828
|
}
|
|
493
829
|
this.observers[event].delete(listener);
|
|
494
830
|
}
|
|
495
|
-
emit(event
|
|
831
|
+
emit(event) {
|
|
832
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
833
|
+
args[_key - 1] = arguments[_key];
|
|
834
|
+
}
|
|
496
835
|
if (this.observers[event]) {
|
|
497
836
|
const cloned = Array.from(this.observers[event].entries());
|
|
498
|
-
cloned.forEach(
|
|
837
|
+
cloned.forEach(_ref => {
|
|
838
|
+
let [observer, numTimesAdded] = _ref;
|
|
499
839
|
for (let i = 0; i < numTimesAdded; i++) {
|
|
500
840
|
observer(...args);
|
|
501
841
|
}
|
|
@@ -503,7 +843,8 @@ class EventEmitter {
|
|
|
503
843
|
}
|
|
504
844
|
if (this.observers['*']) {
|
|
505
845
|
const cloned = Array.from(this.observers['*'].entries());
|
|
506
|
-
cloned.forEach(
|
|
846
|
+
cloned.forEach(_ref2 => {
|
|
847
|
+
let [observer, numTimesAdded] = _ref2;
|
|
507
848
|
for (let i = 0; i < numTimesAdded; i++) {
|
|
508
849
|
observer.apply(observer, [event, ...args]);
|
|
509
850
|
}
|
|
@@ -513,10 +854,11 @@ class EventEmitter {
|
|
|
513
854
|
}
|
|
514
855
|
|
|
515
856
|
class ResourceStore extends EventEmitter {
|
|
516
|
-
constructor(data
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
857
|
+
constructor(data) {
|
|
858
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
859
|
+
ns: ['translation'],
|
|
860
|
+
defaultNS: 'translation'
|
|
861
|
+
};
|
|
520
862
|
super();
|
|
521
863
|
this.data = data || {};
|
|
522
864
|
this.options = options;
|
|
@@ -538,7 +880,8 @@ class ResourceStore extends EventEmitter {
|
|
|
538
880
|
this.options.ns.splice(index, 1);
|
|
539
881
|
}
|
|
540
882
|
}
|
|
541
|
-
getResource(lng, ns, key
|
|
883
|
+
getResource(lng, ns, key) {
|
|
884
|
+
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
542
885
|
const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
|
|
543
886
|
const ignoreJSONStructure = options.ignoreJSONStructure !== undefined ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
|
|
544
887
|
let path;
|
|
@@ -563,11 +906,12 @@ class ResourceStore extends EventEmitter {
|
|
|
563
906
|
key = path.slice(2).join('.');
|
|
564
907
|
}
|
|
565
908
|
if (result || !ignoreJSONStructure || !isString(key)) return result;
|
|
566
|
-
return deepFind(this.data
|
|
909
|
+
return deepFind(this.data && this.data[lng] && this.data[lng][ns], key, keySeparator);
|
|
567
910
|
}
|
|
568
|
-
addResource(lng, ns, key, value
|
|
569
|
-
|
|
570
|
-
|
|
911
|
+
addResource(lng, ns, key, value) {
|
|
912
|
+
let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
|
|
913
|
+
silent: false
|
|
914
|
+
};
|
|
571
915
|
const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
|
|
572
916
|
let path = [lng, ns];
|
|
573
917
|
if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
|
|
@@ -580,9 +924,10 @@ class ResourceStore extends EventEmitter {
|
|
|
580
924
|
setPath(this.data, path, value);
|
|
581
925
|
if (!options.silent) this.emit('added', lng, ns, key, value);
|
|
582
926
|
}
|
|
583
|
-
addResources(lng, ns, resources
|
|
584
|
-
|
|
585
|
-
|
|
927
|
+
addResources(lng, ns, resources) {
|
|
928
|
+
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
|
|
929
|
+
silent: false
|
|
930
|
+
};
|
|
586
931
|
for (const m in resources) {
|
|
587
932
|
if (isString(resources[m]) || Array.isArray(resources[m])) this.addResource(lng, ns, m, resources[m], {
|
|
588
933
|
silent: true
|
|
@@ -590,10 +935,11 @@ class ResourceStore extends EventEmitter {
|
|
|
590
935
|
}
|
|
591
936
|
if (!options.silent) this.emit('added', lng, ns, resources);
|
|
592
937
|
}
|
|
593
|
-
addResourceBundle(lng, ns, resources, deep, overwrite
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
938
|
+
addResourceBundle(lng, ns, resources, deep, overwrite) {
|
|
939
|
+
let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
|
|
940
|
+
silent: false,
|
|
941
|
+
skipCopy: false
|
|
942
|
+
};
|
|
597
943
|
let path = [lng, ns];
|
|
598
944
|
if (lng.indexOf('.') > -1) {
|
|
599
945
|
path = lng.split('.');
|
|
@@ -627,6 +973,10 @@ class ResourceStore extends EventEmitter {
|
|
|
627
973
|
}
|
|
628
974
|
getResourceBundle(lng, ns) {
|
|
629
975
|
if (!ns) ns = this.options.defaultNS;
|
|
976
|
+
if (this.options.compatibilityAPI === 'v1') return {
|
|
977
|
+
...{},
|
|
978
|
+
...this.getResource(lng, ns)
|
|
979
|
+
};
|
|
630
980
|
return this.getResource(lng, ns);
|
|
631
981
|
}
|
|
632
982
|
getDataByLanguage(lng) {
|
|
@@ -649,37 +999,16 @@ var postProcessor = {
|
|
|
649
999
|
},
|
|
650
1000
|
handle(processors, value, key, options, translator) {
|
|
651
1001
|
processors.forEach(processor => {
|
|
652
|
-
value = this.processors[processor]
|
|
1002
|
+
if (this.processors[processor]) value = this.processors[processor].process(value, key, options, translator);
|
|
653
1003
|
});
|
|
654
1004
|
return value;
|
|
655
1005
|
}
|
|
656
1006
|
};
|
|
657
1007
|
|
|
658
|
-
const PATH_KEY = Symbol('i18next/PATH_KEY');
|
|
659
|
-
function createProxy() {
|
|
660
|
-
const state = [];
|
|
661
|
-
const handler = Object.create(null);
|
|
662
|
-
let proxy;
|
|
663
|
-
handler.get = (target, key) => {
|
|
664
|
-
proxy?.revoke?.();
|
|
665
|
-
if (key === PATH_KEY) return state;
|
|
666
|
-
state.push(key);
|
|
667
|
-
proxy = Proxy.revocable(target, handler);
|
|
668
|
-
return proxy.proxy;
|
|
669
|
-
};
|
|
670
|
-
return Proxy.revocable(Object.create(null), handler).proxy;
|
|
671
|
-
}
|
|
672
|
-
function keysFromSelector(selector, opts) {
|
|
673
|
-
const {
|
|
674
|
-
[PATH_KEY]: path
|
|
675
|
-
} = selector(createProxy());
|
|
676
|
-
return path.join(opts?.keySeparator ?? '.');
|
|
677
|
-
}
|
|
678
|
-
|
|
679
1008
|
const checkedLoadedFor = {};
|
|
680
|
-
const shouldHandleAsObject = res => !isString(res) && typeof res !== 'boolean' && typeof res !== 'number';
|
|
681
1009
|
class Translator extends EventEmitter {
|
|
682
|
-
constructor(services
|
|
1010
|
+
constructor(services) {
|
|
1011
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
683
1012
|
super();
|
|
684
1013
|
copy(['resourceStore', 'languageUtils', 'pluralResolver', 'interpolator', 'backendConnector', 'i18nFormat', 'utils'], services, this);
|
|
685
1014
|
this.options = options;
|
|
@@ -691,28 +1020,23 @@ class Translator extends EventEmitter {
|
|
|
691
1020
|
changeLanguage(lng) {
|
|
692
1021
|
if (lng) this.language = lng;
|
|
693
1022
|
}
|
|
694
|
-
exists(key
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
const opt = {
|
|
698
|
-
...o
|
|
1023
|
+
exists(key) {
|
|
1024
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
1025
|
+
interpolation: {}
|
|
699
1026
|
};
|
|
700
|
-
if (key
|
|
701
|
-
const resolved = this.resolve(key, opt);
|
|
702
|
-
if (resolved?.res === undefined) return false;
|
|
703
|
-
const isObject = shouldHandleAsObject(resolved.res);
|
|
704
|
-
if (opt.returnObjects === false && isObject) {
|
|
1027
|
+
if (key === undefined || key === null) {
|
|
705
1028
|
return false;
|
|
706
1029
|
}
|
|
707
|
-
|
|
1030
|
+
const resolved = this.resolve(key, options);
|
|
1031
|
+
return resolved && resolved.res !== undefined;
|
|
708
1032
|
}
|
|
709
|
-
extractFromKey(key,
|
|
710
|
-
let nsSeparator =
|
|
1033
|
+
extractFromKey(key, options) {
|
|
1034
|
+
let nsSeparator = options.nsSeparator !== undefined ? options.nsSeparator : this.options.nsSeparator;
|
|
711
1035
|
if (nsSeparator === undefined) nsSeparator = ':';
|
|
712
|
-
const keySeparator =
|
|
713
|
-
let namespaces =
|
|
1036
|
+
const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
|
|
1037
|
+
let namespaces = options.ns || this.options.defaultNS || [];
|
|
714
1038
|
const wouldCheckForNsInKey = nsSeparator && key.indexOf(nsSeparator) > -1;
|
|
715
|
-
const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !
|
|
1039
|
+
const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !options.keySeparator && !this.options.userDefinedNsSeparator && !options.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
|
|
716
1040
|
if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
|
|
717
1041
|
const m = key.match(this.interpolator.nestingRegexp);
|
|
718
1042
|
if (m && m.length > 0) {
|
|
@@ -730,36 +1054,28 @@ class Translator extends EventEmitter {
|
|
|
730
1054
|
namespaces: isString(namespaces) ? [namespaces] : namespaces
|
|
731
1055
|
};
|
|
732
1056
|
}
|
|
733
|
-
translate(keys,
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
} : o;
|
|
737
|
-
if (typeof opt !== 'object' && this.options.overloadTranslationOptionHandler) {
|
|
738
|
-
opt = this.options.overloadTranslationOptionHandler(arguments);
|
|
1057
|
+
translate(keys, options, lastKey) {
|
|
1058
|
+
if (typeof options !== 'object' && this.options.overloadTranslationOptionHandler) {
|
|
1059
|
+
options = this.options.overloadTranslationOptionHandler(arguments);
|
|
739
1060
|
}
|
|
740
|
-
if (typeof
|
|
741
|
-
...
|
|
1061
|
+
if (typeof options === 'object') options = {
|
|
1062
|
+
...options
|
|
742
1063
|
};
|
|
743
|
-
if (!
|
|
744
|
-
if (keys
|
|
745
|
-
if (typeof keys === 'function') keys = keysFromSelector(keys, {
|
|
746
|
-
...this.options,
|
|
747
|
-
...opt
|
|
748
|
-
});
|
|
1064
|
+
if (!options) options = {};
|
|
1065
|
+
if (keys === undefined || keys === null) return '';
|
|
749
1066
|
if (!Array.isArray(keys)) keys = [String(keys)];
|
|
750
|
-
const returnDetails =
|
|
751
|
-
const keySeparator =
|
|
1067
|
+
const returnDetails = options.returnDetails !== undefined ? options.returnDetails : this.options.returnDetails;
|
|
1068
|
+
const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
|
|
752
1069
|
const {
|
|
753
1070
|
key,
|
|
754
1071
|
namespaces
|
|
755
|
-
} = this.extractFromKey(keys[keys.length - 1],
|
|
1072
|
+
} = this.extractFromKey(keys[keys.length - 1], options);
|
|
756
1073
|
const namespace = namespaces[namespaces.length - 1];
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
const appendNamespaceToCIMode = opt.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode;
|
|
761
|
-
if (lng?.toLowerCase() === 'cimode') {
|
|
1074
|
+
const lng = options.lng || this.language;
|
|
1075
|
+
const appendNamespaceToCIMode = options.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode;
|
|
1076
|
+
if (lng && lng.toLowerCase() === 'cimode') {
|
|
762
1077
|
if (appendNamespaceToCIMode) {
|
|
1078
|
+
const nsSeparator = options.nsSeparator || this.options.nsSeparator;
|
|
763
1079
|
if (returnDetails) {
|
|
764
1080
|
return {
|
|
765
1081
|
res: `${namespace}${nsSeparator}${key}`,
|
|
@@ -767,7 +1083,7 @@ class Translator extends EventEmitter {
|
|
|
767
1083
|
exactUsedKey: key,
|
|
768
1084
|
usedLng: lng,
|
|
769
1085
|
usedNS: namespace,
|
|
770
|
-
usedParams: this.getUsedParamsDetails(
|
|
1086
|
+
usedParams: this.getUsedParamsDetails(options)
|
|
771
1087
|
};
|
|
772
1088
|
}
|
|
773
1089
|
return `${namespace}${nsSeparator}${key}`;
|
|
@@ -779,84 +1095,69 @@ class Translator extends EventEmitter {
|
|
|
779
1095
|
exactUsedKey: key,
|
|
780
1096
|
usedLng: lng,
|
|
781
1097
|
usedNS: namespace,
|
|
782
|
-
usedParams: this.getUsedParamsDetails(
|
|
1098
|
+
usedParams: this.getUsedParamsDetails(options)
|
|
783
1099
|
};
|
|
784
1100
|
}
|
|
785
1101
|
return key;
|
|
786
1102
|
}
|
|
787
|
-
const resolved = this.resolve(keys,
|
|
788
|
-
let res = resolved
|
|
789
|
-
const resUsedKey = resolved
|
|
790
|
-
const resExactUsedKey = resolved
|
|
1103
|
+
const resolved = this.resolve(keys, options);
|
|
1104
|
+
let res = resolved && resolved.res;
|
|
1105
|
+
const resUsedKey = resolved && resolved.usedKey || key;
|
|
1106
|
+
const resExactUsedKey = resolved && resolved.exactUsedKey || key;
|
|
1107
|
+
const resType = Object.prototype.toString.apply(res);
|
|
791
1108
|
const noObject = ['[object Number]', '[object Function]', '[object RegExp]'];
|
|
792
|
-
const joinArrays =
|
|
1109
|
+
const joinArrays = options.joinArrays !== undefined ? options.joinArrays : this.options.joinArrays;
|
|
793
1110
|
const handleAsObjectInI18nFormat = !this.i18nFormat || this.i18nFormat.handleAsObject;
|
|
794
|
-
const
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
const defaultValueSuffixOrdinalFallback = opt.ordinal && needsPluralHandling ? this.pluralResolver.getSuffix(lng, opt.count, {
|
|
798
|
-
ordinal: false
|
|
799
|
-
}) : '';
|
|
800
|
-
const needsZeroSuffixLookup = needsPluralHandling && !opt.ordinal && opt.count === 0;
|
|
801
|
-
const defaultValue = needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] || opt[`defaultValue${defaultValueSuffix}`] || opt[`defaultValue${defaultValueSuffixOrdinalFallback}`] || opt.defaultValue;
|
|
802
|
-
let resForObjHndl = res;
|
|
803
|
-
if (handleAsObjectInI18nFormat && !res && hasDefaultValue) {
|
|
804
|
-
resForObjHndl = defaultValue;
|
|
805
|
-
}
|
|
806
|
-
const handleAsObject = shouldHandleAsObject(resForObjHndl);
|
|
807
|
-
const resType = Object.prototype.toString.apply(resForObjHndl);
|
|
808
|
-
if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && noObject.indexOf(resType) < 0 && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
|
|
809
|
-
if (!opt.returnObjects && !this.options.returnObjects) {
|
|
1111
|
+
const handleAsObject = !isString(res) && typeof res !== 'boolean' && typeof res !== 'number';
|
|
1112
|
+
if (handleAsObjectInI18nFormat && res && handleAsObject && noObject.indexOf(resType) < 0 && !(isString(joinArrays) && Array.isArray(res))) {
|
|
1113
|
+
if (!options.returnObjects && !this.options.returnObjects) {
|
|
810
1114
|
if (!this.options.returnedObjectHandler) {
|
|
811
1115
|
this.logger.warn('accessing an object - but returnObjects options is not enabled!');
|
|
812
1116
|
}
|
|
813
|
-
const r = this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey,
|
|
814
|
-
...
|
|
1117
|
+
const r = this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey, res, {
|
|
1118
|
+
...options,
|
|
815
1119
|
ns: namespaces
|
|
816
1120
|
}) : `key '${key} (${this.language})' returned an object instead of string.`;
|
|
817
1121
|
if (returnDetails) {
|
|
818
1122
|
resolved.res = r;
|
|
819
|
-
resolved.usedParams = this.getUsedParamsDetails(
|
|
1123
|
+
resolved.usedParams = this.getUsedParamsDetails(options);
|
|
820
1124
|
return resolved;
|
|
821
1125
|
}
|
|
822
1126
|
return r;
|
|
823
1127
|
}
|
|
824
1128
|
if (keySeparator) {
|
|
825
|
-
const resTypeIsArray = Array.isArray(
|
|
1129
|
+
const resTypeIsArray = Array.isArray(res);
|
|
826
1130
|
const copy = resTypeIsArray ? [] : {};
|
|
827
1131
|
const newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey;
|
|
828
|
-
for (const m in
|
|
829
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
1132
|
+
for (const m in res) {
|
|
1133
|
+
if (Object.prototype.hasOwnProperty.call(res, m)) {
|
|
830
1134
|
const deepKey = `${newKeyToUse}${keySeparator}${m}`;
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
});
|
|
840
|
-
} else {
|
|
841
|
-
copy[m] = this.translate(deepKey, {
|
|
842
|
-
...opt,
|
|
843
|
-
...{
|
|
844
|
-
joinArrays: false,
|
|
845
|
-
ns: namespaces
|
|
846
|
-
}
|
|
847
|
-
});
|
|
848
|
-
}
|
|
849
|
-
if (copy[m] === deepKey) copy[m] = resForObjHndl[m];
|
|
1135
|
+
copy[m] = this.translate(deepKey, {
|
|
1136
|
+
...options,
|
|
1137
|
+
...{
|
|
1138
|
+
joinArrays: false,
|
|
1139
|
+
ns: namespaces
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
if (copy[m] === deepKey) copy[m] = res[m];
|
|
850
1143
|
}
|
|
851
1144
|
}
|
|
852
1145
|
res = copy;
|
|
853
1146
|
}
|
|
854
1147
|
} else if (handleAsObjectInI18nFormat && isString(joinArrays) && Array.isArray(res)) {
|
|
855
1148
|
res = res.join(joinArrays);
|
|
856
|
-
if (res) res = this.extendTranslation(res, keys,
|
|
1149
|
+
if (res) res = this.extendTranslation(res, keys, options, lastKey);
|
|
857
1150
|
} else {
|
|
858
1151
|
let usedDefault = false;
|
|
859
1152
|
let usedKey = false;
|
|
1153
|
+
const needsPluralHandling = options.count !== undefined && !isString(options.count);
|
|
1154
|
+
const hasDefaultValue = Translator.hasDefaultValue(options);
|
|
1155
|
+
const defaultValueSuffix = needsPluralHandling ? this.pluralResolver.getSuffix(lng, options.count, options) : '';
|
|
1156
|
+
const defaultValueSuffixOrdinalFallback = options.ordinal && needsPluralHandling ? this.pluralResolver.getSuffix(lng, options.count, {
|
|
1157
|
+
ordinal: false
|
|
1158
|
+
}) : '';
|
|
1159
|
+
const needsZeroSuffixLookup = needsPluralHandling && !options.ordinal && options.count === 0 && this.pluralResolver.shouldUseIntlApi();
|
|
1160
|
+
const defaultValue = needsZeroSuffixLookup && options[`defaultValue${this.options.pluralSeparator}zero`] || options[`defaultValue${defaultValueSuffix}`] || options[`defaultValue${defaultValueSuffixOrdinalFallback}`] || options.defaultValue;
|
|
860
1161
|
if (!this.isValidLookup(res) && hasDefaultValue) {
|
|
861
1162
|
usedDefault = true;
|
|
862
1163
|
res = defaultValue;
|
|
@@ -865,47 +1166,47 @@ class Translator extends EventEmitter {
|
|
|
865
1166
|
usedKey = true;
|
|
866
1167
|
res = key;
|
|
867
1168
|
}
|
|
868
|
-
const missingKeyNoValueFallbackToKey =
|
|
1169
|
+
const missingKeyNoValueFallbackToKey = options.missingKeyNoValueFallbackToKey || this.options.missingKeyNoValueFallbackToKey;
|
|
869
1170
|
const resForMissing = missingKeyNoValueFallbackToKey && usedKey ? undefined : res;
|
|
870
1171
|
const updateMissing = hasDefaultValue && defaultValue !== res && this.options.updateMissing;
|
|
871
1172
|
if (usedKey || usedDefault || updateMissing) {
|
|
872
1173
|
this.logger.log(updateMissing ? 'updateKey' : 'missingKey', lng, namespace, key, updateMissing ? defaultValue : res);
|
|
873
1174
|
if (keySeparator) {
|
|
874
1175
|
const fk = this.resolve(key, {
|
|
875
|
-
...
|
|
1176
|
+
...options,
|
|
876
1177
|
keySeparator: false
|
|
877
1178
|
});
|
|
878
1179
|
if (fk && fk.res) this.logger.warn('Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.');
|
|
879
1180
|
}
|
|
880
1181
|
let lngs = [];
|
|
881
|
-
const fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng,
|
|
1182
|
+
const fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, options.lng || this.language);
|
|
882
1183
|
if (this.options.saveMissingTo === 'fallback' && fallbackLngs && fallbackLngs[0]) {
|
|
883
1184
|
for (let i = 0; i < fallbackLngs.length; i++) {
|
|
884
1185
|
lngs.push(fallbackLngs[i]);
|
|
885
1186
|
}
|
|
886
1187
|
} else if (this.options.saveMissingTo === 'all') {
|
|
887
|
-
lngs = this.languageUtils.toResolveHierarchy(
|
|
1188
|
+
lngs = this.languageUtils.toResolveHierarchy(options.lng || this.language);
|
|
888
1189
|
} else {
|
|
889
|
-
lngs.push(
|
|
1190
|
+
lngs.push(options.lng || this.language);
|
|
890
1191
|
}
|
|
891
1192
|
const send = (l, k, specificDefaultValue) => {
|
|
892
1193
|
const defaultForMissing = hasDefaultValue && specificDefaultValue !== res ? specificDefaultValue : resForMissing;
|
|
893
1194
|
if (this.options.missingKeyHandler) {
|
|
894
|
-
this.options.missingKeyHandler(l, namespace, k, defaultForMissing, updateMissing,
|
|
895
|
-
} else if (this.backendConnector
|
|
896
|
-
this.backendConnector.saveMissing(l, namespace, k, defaultForMissing, updateMissing,
|
|
1195
|
+
this.options.missingKeyHandler(l, namespace, k, defaultForMissing, updateMissing, options);
|
|
1196
|
+
} else if (this.backendConnector && this.backendConnector.saveMissing) {
|
|
1197
|
+
this.backendConnector.saveMissing(l, namespace, k, defaultForMissing, updateMissing, options);
|
|
897
1198
|
}
|
|
898
1199
|
this.emit('missingKey', l, namespace, k, res);
|
|
899
1200
|
};
|
|
900
1201
|
if (this.options.saveMissing) {
|
|
901
1202
|
if (this.options.saveMissingPlurals && needsPluralHandling) {
|
|
902
1203
|
lngs.forEach(language => {
|
|
903
|
-
const suffixes = this.pluralResolver.getSuffixes(language,
|
|
904
|
-
if (needsZeroSuffixLookup &&
|
|
1204
|
+
const suffixes = this.pluralResolver.getSuffixes(language, options);
|
|
1205
|
+
if (needsZeroSuffixLookup && options[`defaultValue${this.options.pluralSeparator}zero`] && suffixes.indexOf(`${this.options.pluralSeparator}zero`) < 0) {
|
|
905
1206
|
suffixes.push(`${this.options.pluralSeparator}zero`);
|
|
906
1207
|
}
|
|
907
1208
|
suffixes.forEach(suffix => {
|
|
908
|
-
send([language], key + suffix,
|
|
1209
|
+
send([language], key + suffix, options[`defaultValue${suffix}`] || defaultValue);
|
|
909
1210
|
});
|
|
910
1211
|
});
|
|
911
1212
|
} else {
|
|
@@ -913,80 +1214,87 @@ class Translator extends EventEmitter {
|
|
|
913
1214
|
}
|
|
914
1215
|
}
|
|
915
1216
|
}
|
|
916
|
-
res = this.extendTranslation(res, keys,
|
|
917
|
-
if (usedKey && res === key && this.options.appendNamespaceToMissingKey) {
|
|
918
|
-
res = `${namespace}${nsSeparator}${key}`;
|
|
919
|
-
}
|
|
1217
|
+
res = this.extendTranslation(res, keys, options, resolved, lastKey);
|
|
1218
|
+
if (usedKey && res === key && this.options.appendNamespaceToMissingKey) res = `${namespace}:${key}`;
|
|
920
1219
|
if ((usedKey || usedDefault) && this.options.parseMissingKeyHandler) {
|
|
921
|
-
|
|
1220
|
+
if (this.options.compatibilityAPI !== 'v1') {
|
|
1221
|
+
res = this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey ? `${namespace}:${key}` : key, usedDefault ? res : undefined);
|
|
1222
|
+
} else {
|
|
1223
|
+
res = this.options.parseMissingKeyHandler(res);
|
|
1224
|
+
}
|
|
922
1225
|
}
|
|
923
1226
|
}
|
|
924
1227
|
if (returnDetails) {
|
|
925
1228
|
resolved.res = res;
|
|
926
|
-
resolved.usedParams = this.getUsedParamsDetails(
|
|
1229
|
+
resolved.usedParams = this.getUsedParamsDetails(options);
|
|
927
1230
|
return resolved;
|
|
928
1231
|
}
|
|
929
1232
|
return res;
|
|
930
1233
|
}
|
|
931
|
-
extendTranslation(res, key,
|
|
932
|
-
|
|
1234
|
+
extendTranslation(res, key, options, resolved, lastKey) {
|
|
1235
|
+
var _this = this;
|
|
1236
|
+
if (this.i18nFormat && this.i18nFormat.parse) {
|
|
933
1237
|
res = this.i18nFormat.parse(res, {
|
|
934
1238
|
...this.options.interpolation.defaultVariables,
|
|
935
|
-
...
|
|
936
|
-
},
|
|
1239
|
+
...options
|
|
1240
|
+
}, options.lng || this.language || resolved.usedLng, resolved.usedNS, resolved.usedKey, {
|
|
937
1241
|
resolved
|
|
938
1242
|
});
|
|
939
|
-
} else if (!
|
|
940
|
-
if (
|
|
941
|
-
...
|
|
1243
|
+
} else if (!options.skipInterpolation) {
|
|
1244
|
+
if (options.interpolation) this.interpolator.init({
|
|
1245
|
+
...options,
|
|
942
1246
|
...{
|
|
943
1247
|
interpolation: {
|
|
944
1248
|
...this.options.interpolation,
|
|
945
|
-
...
|
|
1249
|
+
...options.interpolation
|
|
946
1250
|
}
|
|
947
1251
|
}
|
|
948
1252
|
});
|
|
949
|
-
const skipOnVariables = isString(res) && (
|
|
1253
|
+
const skipOnVariables = isString(res) && (options && options.interpolation && options.interpolation.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables);
|
|
950
1254
|
let nestBef;
|
|
951
1255
|
if (skipOnVariables) {
|
|
952
1256
|
const nb = res.match(this.interpolator.nestingRegexp);
|
|
953
1257
|
nestBef = nb && nb.length;
|
|
954
1258
|
}
|
|
955
|
-
let data =
|
|
1259
|
+
let data = options.replace && !isString(options.replace) ? options.replace : options;
|
|
956
1260
|
if (this.options.interpolation.defaultVariables) data = {
|
|
957
1261
|
...this.options.interpolation.defaultVariables,
|
|
958
1262
|
...data
|
|
959
1263
|
};
|
|
960
|
-
res = this.interpolator.interpolate(res, data,
|
|
1264
|
+
res = this.interpolator.interpolate(res, data, options.lng || this.language || resolved.usedLng, options);
|
|
961
1265
|
if (skipOnVariables) {
|
|
962
1266
|
const na = res.match(this.interpolator.nestingRegexp);
|
|
963
1267
|
const nestAft = na && na.length;
|
|
964
|
-
if (nestBef < nestAft)
|
|
1268
|
+
if (nestBef < nestAft) options.nest = false;
|
|
965
1269
|
}
|
|
966
|
-
if (!
|
|
967
|
-
if (
|
|
968
|
-
|
|
969
|
-
|
|
1270
|
+
if (!options.lng && this.options.compatibilityAPI !== 'v1' && resolved && resolved.res) options.lng = this.language || resolved.usedLng;
|
|
1271
|
+
if (options.nest !== false) res = this.interpolator.nest(res, function () {
|
|
1272
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1273
|
+
args[_key] = arguments[_key];
|
|
1274
|
+
}
|
|
1275
|
+
if (lastKey && lastKey[0] === args[0] && !options.context) {
|
|
1276
|
+
_this.logger.warn(`It seems you are nesting recursively key: ${args[0]} in key: ${key[0]}`);
|
|
970
1277
|
return null;
|
|
971
1278
|
}
|
|
972
|
-
return
|
|
973
|
-
},
|
|
974
|
-
if (
|
|
1279
|
+
return _this.translate(...args, key);
|
|
1280
|
+
}, options);
|
|
1281
|
+
if (options.interpolation) this.interpolator.reset();
|
|
975
1282
|
}
|
|
976
|
-
const postProcess =
|
|
1283
|
+
const postProcess = options.postProcess || this.options.postProcess;
|
|
977
1284
|
const postProcessorNames = isString(postProcess) ? [postProcess] : postProcess;
|
|
978
|
-
if (res
|
|
1285
|
+
if (res !== undefined && res !== null && postProcessorNames && postProcessorNames.length && options.applyPostProcessor !== false) {
|
|
979
1286
|
res = postProcessor.handle(postProcessorNames, res, key, this.options && this.options.postProcessPassResolved ? {
|
|
980
1287
|
i18nResolved: {
|
|
981
1288
|
...resolved,
|
|
982
|
-
usedParams: this.getUsedParamsDetails(
|
|
1289
|
+
usedParams: this.getUsedParamsDetails(options)
|
|
983
1290
|
},
|
|
984
|
-
...
|
|
985
|
-
} :
|
|
1291
|
+
...options
|
|
1292
|
+
} : options, this);
|
|
986
1293
|
}
|
|
987
1294
|
return res;
|
|
988
1295
|
}
|
|
989
|
-
resolve(keys
|
|
1296
|
+
resolve(keys) {
|
|
1297
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
990
1298
|
let found;
|
|
991
1299
|
let usedKey;
|
|
992
1300
|
let exactUsedKey;
|
|
@@ -995,19 +1303,19 @@ class Translator extends EventEmitter {
|
|
|
995
1303
|
if (isString(keys)) keys = [keys];
|
|
996
1304
|
keys.forEach(k => {
|
|
997
1305
|
if (this.isValidLookup(found)) return;
|
|
998
|
-
const extracted = this.extractFromKey(k,
|
|
1306
|
+
const extracted = this.extractFromKey(k, options);
|
|
999
1307
|
const key = extracted.key;
|
|
1000
1308
|
usedKey = key;
|
|
1001
1309
|
let namespaces = extracted.namespaces;
|
|
1002
1310
|
if (this.options.fallbackNS) namespaces = namespaces.concat(this.options.fallbackNS);
|
|
1003
|
-
const needsPluralHandling =
|
|
1004
|
-
const needsZeroSuffixLookup = needsPluralHandling && !
|
|
1005
|
-
const needsContextHandling =
|
|
1006
|
-
const codes =
|
|
1311
|
+
const needsPluralHandling = options.count !== undefined && !isString(options.count);
|
|
1312
|
+
const needsZeroSuffixLookup = needsPluralHandling && !options.ordinal && options.count === 0 && this.pluralResolver.shouldUseIntlApi();
|
|
1313
|
+
const needsContextHandling = options.context !== undefined && (isString(options.context) || typeof options.context === 'number') && options.context !== '';
|
|
1314
|
+
const codes = options.lngs ? options.lngs : this.languageUtils.toResolveHierarchy(options.lng || this.language, options.fallbackLng);
|
|
1007
1315
|
namespaces.forEach(ns => {
|
|
1008
1316
|
if (this.isValidLookup(found)) return;
|
|
1009
1317
|
usedNS = ns;
|
|
1010
|
-
if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils
|
|
1318
|
+
if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils && this.utils.hasLoadedNamespace && !this.utils.hasLoadedNamespace(usedNS)) {
|
|
1011
1319
|
checkedLoadedFor[`${codes[0]}-${ns}`] = true;
|
|
1012
1320
|
this.logger.warn(`key "${usedKey}" for languages "${codes.join(', ')}" won't get resolved as namespace "${usedNS}" was not yet loaded`, 'This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!');
|
|
1013
1321
|
}
|
|
@@ -1015,30 +1323,30 @@ class Translator extends EventEmitter {
|
|
|
1015
1323
|
if (this.isValidLookup(found)) return;
|
|
1016
1324
|
usedLng = code;
|
|
1017
1325
|
const finalKeys = [key];
|
|
1018
|
-
if (this.i18nFormat
|
|
1019
|
-
this.i18nFormat.addLookupKeys(finalKeys, key, code, ns,
|
|
1326
|
+
if (this.i18nFormat && this.i18nFormat.addLookupKeys) {
|
|
1327
|
+
this.i18nFormat.addLookupKeys(finalKeys, key, code, ns, options);
|
|
1020
1328
|
} else {
|
|
1021
1329
|
let pluralSuffix;
|
|
1022
|
-
if (needsPluralHandling) pluralSuffix = this.pluralResolver.getSuffix(code,
|
|
1330
|
+
if (needsPluralHandling) pluralSuffix = this.pluralResolver.getSuffix(code, options.count, options);
|
|
1023
1331
|
const zeroSuffix = `${this.options.pluralSeparator}zero`;
|
|
1024
1332
|
const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
|
|
1025
1333
|
if (needsPluralHandling) {
|
|
1026
|
-
|
|
1334
|
+
finalKeys.push(key + pluralSuffix);
|
|
1335
|
+
if (options.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
|
|
1027
1336
|
finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
|
|
1028
1337
|
}
|
|
1029
|
-
finalKeys.push(key + pluralSuffix);
|
|
1030
1338
|
if (needsZeroSuffixLookup) {
|
|
1031
1339
|
finalKeys.push(key + zeroSuffix);
|
|
1032
1340
|
}
|
|
1033
1341
|
}
|
|
1034
1342
|
if (needsContextHandling) {
|
|
1035
|
-
const contextKey = `${key}${this.options.contextSeparator
|
|
1343
|
+
const contextKey = `${key}${this.options.contextSeparator}${options.context}`;
|
|
1036
1344
|
finalKeys.push(contextKey);
|
|
1037
1345
|
if (needsPluralHandling) {
|
|
1038
|
-
|
|
1346
|
+
finalKeys.push(contextKey + pluralSuffix);
|
|
1347
|
+
if (options.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
|
|
1039
1348
|
finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
|
|
1040
1349
|
}
|
|
1041
|
-
finalKeys.push(contextKey + pluralSuffix);
|
|
1042
1350
|
if (needsZeroSuffixLookup) {
|
|
1043
1351
|
finalKeys.push(contextKey + zeroSuffix);
|
|
1044
1352
|
}
|
|
@@ -1049,7 +1357,7 @@ class Translator extends EventEmitter {
|
|
|
1049
1357
|
while (possibleKey = finalKeys.pop()) {
|
|
1050
1358
|
if (!this.isValidLookup(found)) {
|
|
1051
1359
|
exactUsedKey = possibleKey;
|
|
1052
|
-
found = this.getResource(code, ns, possibleKey,
|
|
1360
|
+
found = this.getResource(code, ns, possibleKey, options);
|
|
1053
1361
|
}
|
|
1054
1362
|
}
|
|
1055
1363
|
});
|
|
@@ -1066,11 +1374,13 @@ class Translator extends EventEmitter {
|
|
|
1066
1374
|
isValidLookup(res) {
|
|
1067
1375
|
return res !== undefined && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === '');
|
|
1068
1376
|
}
|
|
1069
|
-
getResource(code, ns, key
|
|
1070
|
-
|
|
1377
|
+
getResource(code, ns, key) {
|
|
1378
|
+
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1379
|
+
if (this.i18nFormat && this.i18nFormat.getResource) return this.i18nFormat.getResource(code, ns, key, options);
|
|
1071
1380
|
return this.resourceStore.getResource(code, ns, key, options);
|
|
1072
1381
|
}
|
|
1073
|
-
getUsedParamsDetails(
|
|
1382
|
+
getUsedParamsDetails() {
|
|
1383
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1074
1384
|
const optionsKeys = ['defaultValue', 'ordinal', 'context', 'replace', 'lng', 'lngs', 'fallbackLng', 'ns', 'keySeparator', 'nsSeparator', 'returnObjects', 'returnDetails', 'joinArrays', 'postProcess', 'interpolation'];
|
|
1075
1385
|
const useOptionsReplaceForData = options.replace && !isString(options.replace);
|
|
1076
1386
|
let data = useOptionsReplaceForData ? options.replace : options;
|
|
@@ -1104,6 +1414,7 @@ class Translator extends EventEmitter {
|
|
|
1104
1414
|
}
|
|
1105
1415
|
}
|
|
1106
1416
|
|
|
1417
|
+
const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1);
|
|
1107
1418
|
class LanguageUtil {
|
|
1108
1419
|
constructor(options) {
|
|
1109
1420
|
this.options = options;
|
|
@@ -1127,18 +1438,31 @@ class LanguageUtil {
|
|
|
1127
1438
|
}
|
|
1128
1439
|
formatLanguageCode(code) {
|
|
1129
1440
|
if (isString(code) && code.indexOf('-') > -1) {
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1441
|
+
if (typeof Intl !== 'undefined' && typeof Intl.getCanonicalLocales !== 'undefined') {
|
|
1442
|
+
try {
|
|
1443
|
+
let formattedCode = Intl.getCanonicalLocales(code)[0];
|
|
1444
|
+
if (formattedCode && this.options.lowerCaseLng) {
|
|
1445
|
+
formattedCode = formattedCode.toLowerCase();
|
|
1446
|
+
}
|
|
1447
|
+
if (formattedCode) return formattedCode;
|
|
1448
|
+
} catch (e) {}
|
|
1136
1449
|
}
|
|
1137
|
-
|
|
1450
|
+
const specialCases = ['hans', 'hant', 'latn', 'cyrl', 'cans', 'mong', 'arab'];
|
|
1451
|
+
let p = code.split('-');
|
|
1138
1452
|
if (this.options.lowerCaseLng) {
|
|
1139
|
-
|
|
1453
|
+
p = p.map(part => part.toLowerCase());
|
|
1454
|
+
} else if (p.length === 2) {
|
|
1455
|
+
p[0] = p[0].toLowerCase();
|
|
1456
|
+
p[1] = p[1].toUpperCase();
|
|
1457
|
+
if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
|
|
1458
|
+
} else if (p.length === 3) {
|
|
1459
|
+
p[0] = p[0].toLowerCase();
|
|
1460
|
+
if (p[1].length === 2) p[1] = p[1].toUpperCase();
|
|
1461
|
+
if (p[0] !== 'sgn' && p[2].length === 2) p[2] = p[2].toUpperCase();
|
|
1462
|
+
if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
|
|
1463
|
+
if (specialCases.indexOf(p[2].toLowerCase()) > -1) p[2] = capitalize(p[2].toLowerCase());
|
|
1140
1464
|
}
|
|
1141
|
-
return
|
|
1465
|
+
return p.join('-');
|
|
1142
1466
|
}
|
|
1143
1467
|
return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code;
|
|
1144
1468
|
}
|
|
@@ -1159,8 +1483,6 @@ class LanguageUtil {
|
|
|
1159
1483
|
if (!found && this.options.supportedLngs) {
|
|
1160
1484
|
codes.forEach(code => {
|
|
1161
1485
|
if (found) return;
|
|
1162
|
-
const lngScOnly = this.getScriptPartFromCode(code);
|
|
1163
|
-
if (this.isSupportedCode(lngScOnly)) return found = lngScOnly;
|
|
1164
1486
|
const lngOnly = this.getLanguagePartFromCode(code);
|
|
1165
1487
|
if (this.isSupportedCode(lngOnly)) return found = lngOnly;
|
|
1166
1488
|
found = this.options.supportedLngs.find(supportedLng => {
|
|
@@ -1188,7 +1510,7 @@ class LanguageUtil {
|
|
|
1188
1510
|
return found || [];
|
|
1189
1511
|
}
|
|
1190
1512
|
toResolveHierarchy(code, fallbackCode) {
|
|
1191
|
-
const fallbackCodes = this.getFallbackCodes(
|
|
1513
|
+
const fallbackCodes = this.getFallbackCodes(fallbackCode || this.options.fallbackLng || [], code);
|
|
1192
1514
|
const codes = [];
|
|
1193
1515
|
const addCode = c => {
|
|
1194
1516
|
if (!c) return;
|
|
@@ -1212,6 +1534,125 @@ class LanguageUtil {
|
|
|
1212
1534
|
}
|
|
1213
1535
|
}
|
|
1214
1536
|
|
|
1537
|
+
let sets = [{
|
|
1538
|
+
lngs: ['ach', 'ak', 'am', 'arn', 'br', 'fil', 'gun', 'ln', 'mfe', 'mg', 'mi', 'oc', 'pt', 'pt-BR', 'tg', 'tl', 'ti', 'tr', 'uz', 'wa'],
|
|
1539
|
+
nr: [1, 2],
|
|
1540
|
+
fc: 1
|
|
1541
|
+
}, {
|
|
1542
|
+
lngs: ['af', 'an', 'ast', 'az', 'bg', 'bn', 'ca', 'da', 'de', 'dev', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fi', 'fo', 'fur', 'fy', 'gl', 'gu', 'ha', 'hi', 'hu', 'hy', 'ia', 'it', 'kk', 'kn', 'ku', 'lb', 'mai', 'ml', 'mn', 'mr', 'nah', 'nap', 'nb', 'ne', 'nl', 'nn', 'no', 'nso', 'pa', 'pap', 'pms', 'ps', 'pt-PT', 'rm', 'sco', 'se', 'si', 'so', 'son', 'sq', 'sv', 'sw', 'ta', 'te', 'tk', 'ur', 'yo'],
|
|
1543
|
+
nr: [1, 2],
|
|
1544
|
+
fc: 2
|
|
1545
|
+
}, {
|
|
1546
|
+
lngs: ['ay', 'bo', 'cgg', 'fa', 'ht', 'id', 'ja', 'jbo', 'ka', 'km', 'ko', 'ky', 'lo', 'ms', 'sah', 'su', 'th', 'tt', 'ug', 'vi', 'wo', 'zh'],
|
|
1547
|
+
nr: [1],
|
|
1548
|
+
fc: 3
|
|
1549
|
+
}, {
|
|
1550
|
+
lngs: ['be', 'bs', 'cnr', 'dz', 'hr', 'ru', 'sr', 'uk'],
|
|
1551
|
+
nr: [1, 2, 5],
|
|
1552
|
+
fc: 4
|
|
1553
|
+
}, {
|
|
1554
|
+
lngs: ['ar'],
|
|
1555
|
+
nr: [0, 1, 2, 3, 11, 100],
|
|
1556
|
+
fc: 5
|
|
1557
|
+
}, {
|
|
1558
|
+
lngs: ['cs', 'sk'],
|
|
1559
|
+
nr: [1, 2, 5],
|
|
1560
|
+
fc: 6
|
|
1561
|
+
}, {
|
|
1562
|
+
lngs: ['csb', 'pl'],
|
|
1563
|
+
nr: [1, 2, 5],
|
|
1564
|
+
fc: 7
|
|
1565
|
+
}, {
|
|
1566
|
+
lngs: ['cy'],
|
|
1567
|
+
nr: [1, 2, 3, 8],
|
|
1568
|
+
fc: 8
|
|
1569
|
+
}, {
|
|
1570
|
+
lngs: ['fr'],
|
|
1571
|
+
nr: [1, 2],
|
|
1572
|
+
fc: 9
|
|
1573
|
+
}, {
|
|
1574
|
+
lngs: ['ga'],
|
|
1575
|
+
nr: [1, 2, 3, 7, 11],
|
|
1576
|
+
fc: 10
|
|
1577
|
+
}, {
|
|
1578
|
+
lngs: ['gd'],
|
|
1579
|
+
nr: [1, 2, 3, 20],
|
|
1580
|
+
fc: 11
|
|
1581
|
+
}, {
|
|
1582
|
+
lngs: ['is'],
|
|
1583
|
+
nr: [1, 2],
|
|
1584
|
+
fc: 12
|
|
1585
|
+
}, {
|
|
1586
|
+
lngs: ['jv'],
|
|
1587
|
+
nr: [0, 1],
|
|
1588
|
+
fc: 13
|
|
1589
|
+
}, {
|
|
1590
|
+
lngs: ['kw'],
|
|
1591
|
+
nr: [1, 2, 3, 4],
|
|
1592
|
+
fc: 14
|
|
1593
|
+
}, {
|
|
1594
|
+
lngs: ['lt'],
|
|
1595
|
+
nr: [1, 2, 10],
|
|
1596
|
+
fc: 15
|
|
1597
|
+
}, {
|
|
1598
|
+
lngs: ['lv'],
|
|
1599
|
+
nr: [1, 2, 0],
|
|
1600
|
+
fc: 16
|
|
1601
|
+
}, {
|
|
1602
|
+
lngs: ['mk'],
|
|
1603
|
+
nr: [1, 2],
|
|
1604
|
+
fc: 17
|
|
1605
|
+
}, {
|
|
1606
|
+
lngs: ['mnk'],
|
|
1607
|
+
nr: [0, 1, 2],
|
|
1608
|
+
fc: 18
|
|
1609
|
+
}, {
|
|
1610
|
+
lngs: ['mt'],
|
|
1611
|
+
nr: [1, 2, 11, 20],
|
|
1612
|
+
fc: 19
|
|
1613
|
+
}, {
|
|
1614
|
+
lngs: ['or'],
|
|
1615
|
+
nr: [2, 1],
|
|
1616
|
+
fc: 2
|
|
1617
|
+
}, {
|
|
1618
|
+
lngs: ['ro'],
|
|
1619
|
+
nr: [1, 2, 20],
|
|
1620
|
+
fc: 20
|
|
1621
|
+
}, {
|
|
1622
|
+
lngs: ['sl'],
|
|
1623
|
+
nr: [5, 1, 2, 3],
|
|
1624
|
+
fc: 21
|
|
1625
|
+
}, {
|
|
1626
|
+
lngs: ['he', 'iw'],
|
|
1627
|
+
nr: [1, 2, 20, 21],
|
|
1628
|
+
fc: 22
|
|
1629
|
+
}];
|
|
1630
|
+
let _rulesPluralsTypes = {
|
|
1631
|
+
1: n => Number(n > 1),
|
|
1632
|
+
2: n => Number(n != 1),
|
|
1633
|
+
3: n => 0,
|
|
1634
|
+
4: n => Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2),
|
|
1635
|
+
5: n => Number(n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5),
|
|
1636
|
+
6: n => Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2),
|
|
1637
|
+
7: n => Number(n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2),
|
|
1638
|
+
8: n => Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3),
|
|
1639
|
+
9: n => Number(n >= 2),
|
|
1640
|
+
10: n => Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4),
|
|
1641
|
+
11: n => Number(n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3),
|
|
1642
|
+
12: n => Number(n % 10 != 1 || n % 100 == 11),
|
|
1643
|
+
13: n => Number(n !== 0),
|
|
1644
|
+
14: n => Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3),
|
|
1645
|
+
15: n => Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2),
|
|
1646
|
+
16: n => Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2),
|
|
1647
|
+
17: n => Number(n == 1 || n % 10 == 1 && n % 100 != 11 ? 0 : 1),
|
|
1648
|
+
18: n => Number(n == 0 ? 0 : n == 1 ? 1 : 2),
|
|
1649
|
+
19: n => Number(n == 1 ? 0 : n == 0 || n % 100 > 1 && n % 100 < 11 ? 1 : n % 100 > 10 && n % 100 < 20 ? 2 : 3),
|
|
1650
|
+
20: n => Number(n == 1 ? 0 : n == 0 || n % 100 > 0 && n % 100 < 20 ? 1 : 2),
|
|
1651
|
+
21: n => Number(n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0),
|
|
1652
|
+
22: n => Number(n == 1 ? 0 : n == 2 ? 1 : (n < 0 || n > 10) && n % 10 == 0 ? 2 : 3)
|
|
1653
|
+
};
|
|
1654
|
+
const nonIntlVersions = ['v1', 'v2', 'v3'];
|
|
1655
|
+
const intlVersions = ['v4'];
|
|
1215
1656
|
const suffixesOrder = {
|
|
1216
1657
|
zero: 0,
|
|
1217
1658
|
one: 1,
|
|
@@ -1220,74 +1661,129 @@ const suffixesOrder = {
|
|
|
1220
1661
|
many: 4,
|
|
1221
1662
|
other: 5
|
|
1222
1663
|
};
|
|
1223
|
-
const
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1664
|
+
const createRules = () => {
|
|
1665
|
+
const rules = {};
|
|
1666
|
+
sets.forEach(set => {
|
|
1667
|
+
set.lngs.forEach(l => {
|
|
1668
|
+
rules[l] = {
|
|
1669
|
+
numbers: set.nr,
|
|
1670
|
+
plurals: _rulesPluralsTypes[set.fc]
|
|
1671
|
+
};
|
|
1672
|
+
});
|
|
1673
|
+
});
|
|
1674
|
+
return rules;
|
|
1228
1675
|
};
|
|
1229
1676
|
class PluralResolver {
|
|
1230
|
-
constructor(languageUtils
|
|
1677
|
+
constructor(languageUtils) {
|
|
1678
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1231
1679
|
this.languageUtils = languageUtils;
|
|
1232
1680
|
this.options = options;
|
|
1233
1681
|
this.logger = baseLogger.create('pluralResolver');
|
|
1682
|
+
if ((!this.options.compatibilityJSON || intlVersions.includes(this.options.compatibilityJSON)) && (typeof Intl === 'undefined' || !Intl.PluralRules)) {
|
|
1683
|
+
this.options.compatibilityJSON = 'v3';
|
|
1684
|
+
this.logger.error('Your environment seems not to be Intl API compatible, use an Intl.PluralRules polyfill. Will fallback to the compatibilityJSON v3 format handling.');
|
|
1685
|
+
}
|
|
1686
|
+
this.rules = createRules();
|
|
1234
1687
|
this.pluralRulesCache = {};
|
|
1235
1688
|
}
|
|
1689
|
+
addRule(lng, obj) {
|
|
1690
|
+
this.rules[lng] = obj;
|
|
1691
|
+
}
|
|
1236
1692
|
clearCache() {
|
|
1237
1693
|
this.pluralRulesCache = {};
|
|
1238
1694
|
}
|
|
1239
|
-
getRule(code
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
if (cacheKey in this.pluralRulesCache) {
|
|
1247
|
-
return this.pluralRulesCache[cacheKey];
|
|
1248
|
-
}
|
|
1249
|
-
let rule;
|
|
1250
|
-
try {
|
|
1251
|
-
rule = new Intl.PluralRules(cleanedCode, {
|
|
1695
|
+
getRule(code) {
|
|
1696
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1697
|
+
if (this.shouldUseIntlApi()) {
|
|
1698
|
+
const cleanedCode = getCleanedCode(code === 'dev' ? 'en' : code);
|
|
1699
|
+
const type = options.ordinal ? 'ordinal' : 'cardinal';
|
|
1700
|
+
const cacheKey = JSON.stringify({
|
|
1701
|
+
cleanedCode,
|
|
1252
1702
|
type
|
|
1253
1703
|
});
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1704
|
+
if (cacheKey in this.pluralRulesCache) {
|
|
1705
|
+
return this.pluralRulesCache[cacheKey];
|
|
1706
|
+
}
|
|
1707
|
+
let rule;
|
|
1708
|
+
try {
|
|
1709
|
+
rule = new Intl.PluralRules(cleanedCode, {
|
|
1710
|
+
type
|
|
1711
|
+
});
|
|
1712
|
+
} catch (err) {
|
|
1713
|
+
if (!code.match(/-|_/)) return;
|
|
1714
|
+
const lngPart = this.languageUtils.getLanguagePartFromCode(code);
|
|
1715
|
+
rule = this.getRule(lngPart, options);
|
|
1258
1716
|
}
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
rule = this.getRule(lngPart, options);
|
|
1717
|
+
this.pluralRulesCache[cacheKey] = rule;
|
|
1718
|
+
return rule;
|
|
1262
1719
|
}
|
|
1263
|
-
this.
|
|
1264
|
-
return rule;
|
|
1720
|
+
return this.rules[code] || this.rules[this.languageUtils.getLanguagePartFromCode(code)];
|
|
1265
1721
|
}
|
|
1266
|
-
needsPlural(code
|
|
1267
|
-
let
|
|
1268
|
-
|
|
1269
|
-
|
|
1722
|
+
needsPlural(code) {
|
|
1723
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1724
|
+
const rule = this.getRule(code, options);
|
|
1725
|
+
if (this.shouldUseIntlApi()) {
|
|
1726
|
+
return rule && rule.resolvedOptions().pluralCategories.length > 1;
|
|
1727
|
+
}
|
|
1728
|
+
return rule && rule.numbers.length > 1;
|
|
1270
1729
|
}
|
|
1271
|
-
getPluralFormsOfKey(code, key
|
|
1730
|
+
getPluralFormsOfKey(code, key) {
|
|
1731
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1272
1732
|
return this.getSuffixes(code, options).map(suffix => `${key}${suffix}`);
|
|
1273
1733
|
}
|
|
1274
|
-
getSuffixes(code
|
|
1275
|
-
let
|
|
1276
|
-
|
|
1277
|
-
if (!rule)
|
|
1278
|
-
|
|
1734
|
+
getSuffixes(code) {
|
|
1735
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1736
|
+
const rule = this.getRule(code, options);
|
|
1737
|
+
if (!rule) {
|
|
1738
|
+
return [];
|
|
1739
|
+
}
|
|
1740
|
+
if (this.shouldUseIntlApi()) {
|
|
1741
|
+
return rule.resolvedOptions().pluralCategories.sort((pluralCategory1, pluralCategory2) => suffixesOrder[pluralCategory1] - suffixesOrder[pluralCategory2]).map(pluralCategory => `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ''}${pluralCategory}`);
|
|
1742
|
+
}
|
|
1743
|
+
return rule.numbers.map(number => this.getSuffix(code, number, options));
|
|
1279
1744
|
}
|
|
1280
|
-
getSuffix(code, count
|
|
1745
|
+
getSuffix(code, count) {
|
|
1746
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1281
1747
|
const rule = this.getRule(code, options);
|
|
1282
1748
|
if (rule) {
|
|
1283
|
-
|
|
1749
|
+
if (this.shouldUseIntlApi()) {
|
|
1750
|
+
return `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ''}${rule.select(count)}`;
|
|
1751
|
+
}
|
|
1752
|
+
return this.getSuffixRetroCompatible(rule, count);
|
|
1284
1753
|
}
|
|
1285
1754
|
this.logger.warn(`no plural rule found for: ${code}`);
|
|
1286
|
-
return
|
|
1755
|
+
return '';
|
|
1756
|
+
}
|
|
1757
|
+
getSuffixRetroCompatible(rule, count) {
|
|
1758
|
+
const idx = rule.noAbs ? rule.plurals(count) : rule.plurals(Math.abs(count));
|
|
1759
|
+
let suffix = rule.numbers[idx];
|
|
1760
|
+
if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
|
|
1761
|
+
if (suffix === 2) {
|
|
1762
|
+
suffix = 'plural';
|
|
1763
|
+
} else if (suffix === 1) {
|
|
1764
|
+
suffix = '';
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
const returnSuffix = () => this.options.prepend && suffix.toString() ? this.options.prepend + suffix.toString() : suffix.toString();
|
|
1768
|
+
if (this.options.compatibilityJSON === 'v1') {
|
|
1769
|
+
if (suffix === 1) return '';
|
|
1770
|
+
if (typeof suffix === 'number') return `_plural_${suffix.toString()}`;
|
|
1771
|
+
return returnSuffix();
|
|
1772
|
+
} else if (this.options.compatibilityJSON === 'v2') {
|
|
1773
|
+
return returnSuffix();
|
|
1774
|
+
} else if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
|
|
1775
|
+
return returnSuffix();
|
|
1776
|
+
}
|
|
1777
|
+
return this.options.prepend && idx.toString() ? this.options.prepend + idx.toString() : idx.toString();
|
|
1778
|
+
}
|
|
1779
|
+
shouldUseIntlApi() {
|
|
1780
|
+
return !nonIntlVersions.includes(this.options.compatibilityJSON);
|
|
1287
1781
|
}
|
|
1288
1782
|
}
|
|
1289
1783
|
|
|
1290
|
-
const deepFindWithDefaults = (data, defaultData, key
|
|
1784
|
+
const deepFindWithDefaults = function (data, defaultData, key) {
|
|
1785
|
+
let keySeparator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '.';
|
|
1786
|
+
let ignoreJSONStructure = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
|
1291
1787
|
let path = getPathWithDefaults(data, defaultData, key);
|
|
1292
1788
|
if (!path && ignoreJSONStructure && isString(key)) {
|
|
1293
1789
|
path = deepFind(data, key, keySeparator);
|
|
@@ -1297,13 +1793,15 @@ const deepFindWithDefaults = (data, defaultData, key, keySeparator = '.', ignore
|
|
|
1297
1793
|
};
|
|
1298
1794
|
const regexSafe = val => val.replace(/\$/g, '$$$$');
|
|
1299
1795
|
class Interpolator {
|
|
1300
|
-
constructor(
|
|
1796
|
+
constructor() {
|
|
1797
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1301
1798
|
this.logger = baseLogger.create('interpolator');
|
|
1302
1799
|
this.options = options;
|
|
1303
|
-
this.format = options
|
|
1800
|
+
this.format = options.interpolation && options.interpolation.format || (value => value);
|
|
1304
1801
|
this.init(options);
|
|
1305
1802
|
}
|
|
1306
|
-
init(
|
|
1803
|
+
init() {
|
|
1804
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1307
1805
|
if (!options.interpolation) options.interpolation = {
|
|
1308
1806
|
escapeValue: true
|
|
1309
1807
|
};
|
|
@@ -1346,7 +1844,7 @@ class Interpolator {
|
|
|
1346
1844
|
}
|
|
1347
1845
|
resetRegExp() {
|
|
1348
1846
|
const getOrResetRegExp = (existingRegExp, pattern) => {
|
|
1349
|
-
if (existingRegExp
|
|
1847
|
+
if (existingRegExp && existingRegExp.source === pattern) {
|
|
1350
1848
|
existingRegExp.lastIndex = 0;
|
|
1351
1849
|
return existingRegExp;
|
|
1352
1850
|
}
|
|
@@ -1354,7 +1852,7 @@ class Interpolator {
|
|
|
1354
1852
|
};
|
|
1355
1853
|
this.regexp = getOrResetRegExp(this.regexp, `${this.prefix}(.+?)${this.suffix}`);
|
|
1356
1854
|
this.regexpUnescape = getOrResetRegExp(this.regexpUnescape, `${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`);
|
|
1357
|
-
this.nestingRegexp = getOrResetRegExp(this.nestingRegexp, `${this.nestingPrefix}(
|
|
1855
|
+
this.nestingRegexp = getOrResetRegExp(this.nestingRegexp, `${this.nestingPrefix}(.+?)${this.nestingSuffix}`);
|
|
1358
1856
|
}
|
|
1359
1857
|
interpolate(str, data, lng, options) {
|
|
1360
1858
|
let match;
|
|
@@ -1380,8 +1878,8 @@ class Interpolator {
|
|
|
1380
1878
|
});
|
|
1381
1879
|
};
|
|
1382
1880
|
this.resetRegExp();
|
|
1383
|
-
const missingInterpolationHandler = options
|
|
1384
|
-
const skipOnVariables = options
|
|
1881
|
+
const missingInterpolationHandler = options && options.missingInterpolationHandler || this.options.missingInterpolationHandler;
|
|
1882
|
+
const skipOnVariables = options && options.interpolation && options.interpolation.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
|
|
1385
1883
|
const todos = [{
|
|
1386
1884
|
regex: this.regexpUnescape,
|
|
1387
1885
|
safeValue: val => regexSafe(val)
|
|
@@ -1426,20 +1924,21 @@ class Interpolator {
|
|
|
1426
1924
|
});
|
|
1427
1925
|
return str;
|
|
1428
1926
|
}
|
|
1429
|
-
nest(str, fc
|
|
1927
|
+
nest(str, fc) {
|
|
1928
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1430
1929
|
let match;
|
|
1431
1930
|
let value;
|
|
1432
1931
|
let clonedOptions;
|
|
1433
1932
|
const handleHasOptions = (key, inheritedOptions) => {
|
|
1434
1933
|
const sep = this.nestingOptionsSeparator;
|
|
1435
1934
|
if (key.indexOf(sep) < 0) return key;
|
|
1436
|
-
const c = key.split(new RegExp(`${
|
|
1935
|
+
const c = key.split(new RegExp(`${sep}[ ]*{`));
|
|
1437
1936
|
let optionsString = `{${c[1]}`;
|
|
1438
1937
|
key = c[0];
|
|
1439
1938
|
optionsString = this.interpolate(optionsString, clonedOptions);
|
|
1440
1939
|
const matchedSingleQuotes = optionsString.match(/'/g);
|
|
1441
1940
|
const matchedDoubleQuotes = optionsString.match(/"/g);
|
|
1442
|
-
if (
|
|
1941
|
+
if (matchedSingleQuotes && matchedSingleQuotes.length % 2 === 0 && !matchedDoubleQuotes || matchedDoubleQuotes.length % 2 !== 0) {
|
|
1443
1942
|
optionsString = optionsString.replace(/'/g, '"');
|
|
1444
1943
|
}
|
|
1445
1944
|
try {
|
|
@@ -1463,10 +1962,12 @@ class Interpolator {
|
|
|
1463
1962
|
clonedOptions = clonedOptions.replace && !isString(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
|
|
1464
1963
|
clonedOptions.applyPostProcessor = false;
|
|
1465
1964
|
delete clonedOptions.defaultValue;
|
|
1466
|
-
|
|
1467
|
-
if (
|
|
1468
|
-
|
|
1469
|
-
match[1] =
|
|
1965
|
+
let doReduce = false;
|
|
1966
|
+
if (match[0].indexOf(this.formatSeparator) !== -1 && !/{.*}/.test(match[1])) {
|
|
1967
|
+
const r = match[1].split(this.formatSeparator).map(elem => elem.trim());
|
|
1968
|
+
match[1] = r.shift();
|
|
1969
|
+
formatters = r;
|
|
1970
|
+
doReduce = true;
|
|
1470
1971
|
}
|
|
1471
1972
|
value = fc(handleHasOptions.call(this, match[1].trim(), clonedOptions), clonedOptions);
|
|
1472
1973
|
if (value && match[0] === str && !isString(value)) return value;
|
|
@@ -1475,7 +1976,7 @@ class Interpolator {
|
|
|
1475
1976
|
this.logger.warn(`missed to resolve ${match[1]} for nesting ${str}`);
|
|
1476
1977
|
value = '';
|
|
1477
1978
|
}
|
|
1478
|
-
if (
|
|
1979
|
+
if (doReduce) {
|
|
1479
1980
|
value = formatters.reduce((v, f) => this.format(v, f, options.lng, {
|
|
1480
1981
|
...options,
|
|
1481
1982
|
interpolationkey: match[1].trim()
|
|
@@ -1521,68 +2022,68 @@ const parseFormatStr = formatStr => {
|
|
|
1521
2022
|
};
|
|
1522
2023
|
const createCachedFormatter = fn => {
|
|
1523
2024
|
const cache = {};
|
|
1524
|
-
return (
|
|
1525
|
-
let optForCache =
|
|
1526
|
-
if (
|
|
2025
|
+
return (val, lng, options) => {
|
|
2026
|
+
let optForCache = options;
|
|
2027
|
+
if (options && options.interpolationkey && options.formatParams && options.formatParams[options.interpolationkey] && options[options.interpolationkey]) {
|
|
1527
2028
|
optForCache = {
|
|
1528
2029
|
...optForCache,
|
|
1529
|
-
[
|
|
2030
|
+
[options.interpolationkey]: undefined
|
|
1530
2031
|
};
|
|
1531
2032
|
}
|
|
1532
|
-
const key =
|
|
1533
|
-
let
|
|
1534
|
-
if (!
|
|
1535
|
-
|
|
1536
|
-
cache[key] =
|
|
2033
|
+
const key = lng + JSON.stringify(optForCache);
|
|
2034
|
+
let formatter = cache[key];
|
|
2035
|
+
if (!formatter) {
|
|
2036
|
+
formatter = fn(getCleanedCode(lng), options);
|
|
2037
|
+
cache[key] = formatter;
|
|
1537
2038
|
}
|
|
1538
|
-
return
|
|
2039
|
+
return formatter(val);
|
|
1539
2040
|
};
|
|
1540
2041
|
};
|
|
1541
|
-
const createNonCachedFormatter = fn => (v, l, o) => fn(getCleanedCode(l), o)(v);
|
|
1542
2042
|
class Formatter {
|
|
1543
|
-
constructor(
|
|
2043
|
+
constructor() {
|
|
2044
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1544
2045
|
this.logger = baseLogger.create('formatter');
|
|
1545
2046
|
this.options = options;
|
|
1546
|
-
this.init(options);
|
|
1547
|
-
}
|
|
1548
|
-
init(services, options = {
|
|
1549
|
-
interpolation: {}
|
|
1550
|
-
}) {
|
|
1551
|
-
this.formatSeparator = options.interpolation.formatSeparator || ',';
|
|
1552
|
-
const cf = options.cacheInBuiltFormats ? createCachedFormatter : createNonCachedFormatter;
|
|
1553
2047
|
this.formats = {
|
|
1554
|
-
number:
|
|
2048
|
+
number: createCachedFormatter((lng, opt) => {
|
|
1555
2049
|
const formatter = new Intl.NumberFormat(lng, {
|
|
1556
2050
|
...opt
|
|
1557
2051
|
});
|
|
1558
2052
|
return val => formatter.format(val);
|
|
1559
2053
|
}),
|
|
1560
|
-
currency:
|
|
2054
|
+
currency: createCachedFormatter((lng, opt) => {
|
|
1561
2055
|
const formatter = new Intl.NumberFormat(lng, {
|
|
1562
2056
|
...opt,
|
|
1563
2057
|
style: 'currency'
|
|
1564
2058
|
});
|
|
1565
2059
|
return val => formatter.format(val);
|
|
1566
2060
|
}),
|
|
1567
|
-
datetime:
|
|
2061
|
+
datetime: createCachedFormatter((lng, opt) => {
|
|
1568
2062
|
const formatter = new Intl.DateTimeFormat(lng, {
|
|
1569
2063
|
...opt
|
|
1570
2064
|
});
|
|
1571
2065
|
return val => formatter.format(val);
|
|
1572
2066
|
}),
|
|
1573
|
-
relativetime:
|
|
2067
|
+
relativetime: createCachedFormatter((lng, opt) => {
|
|
1574
2068
|
const formatter = new Intl.RelativeTimeFormat(lng, {
|
|
1575
2069
|
...opt
|
|
1576
2070
|
});
|
|
1577
2071
|
return val => formatter.format(val, opt.range || 'day');
|
|
1578
2072
|
}),
|
|
1579
|
-
list:
|
|
2073
|
+
list: createCachedFormatter((lng, opt) => {
|
|
1580
2074
|
const formatter = new Intl.ListFormat(lng, {
|
|
1581
2075
|
...opt
|
|
1582
2076
|
});
|
|
1583
2077
|
return val => formatter.format(val);
|
|
1584
2078
|
})
|
|
1585
2079
|
};
|
|
2080
|
+
this.init(options);
|
|
2081
|
+
}
|
|
2082
|
+
init(services) {
|
|
2083
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
2084
|
+
interpolation: {}
|
|
2085
|
+
};
|
|
2086
|
+
this.formatSeparator = options.interpolation.formatSeparator || ',';
|
|
1586
2087
|
}
|
|
1587
2088
|
add(name, fc) {
|
|
1588
2089
|
this.formats[name.toLowerCase().trim()] = fc;
|
|
@@ -1590,7 +2091,8 @@ class Formatter {
|
|
|
1590
2091
|
addCached(name, fc) {
|
|
1591
2092
|
this.formats[name.toLowerCase().trim()] = createCachedFormatter(fc);
|
|
1592
2093
|
}
|
|
1593
|
-
format(value, format, lng
|
|
2094
|
+
format(value, format, lng) {
|
|
2095
|
+
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1594
2096
|
const formats = format.split(this.formatSeparator);
|
|
1595
2097
|
if (formats.length > 1 && formats[0].indexOf('(') > 1 && formats[0].indexOf(')') < 0 && formats.find(f => f.indexOf(')') > -1)) {
|
|
1596
2098
|
const lastIndex = formats.findIndex(f => f.indexOf(')') > -1);
|
|
@@ -1604,7 +2106,7 @@ class Formatter {
|
|
|
1604
2106
|
if (this.formats[formatName]) {
|
|
1605
2107
|
let formatted = mem;
|
|
1606
2108
|
try {
|
|
1607
|
-
const valOptions = options
|
|
2109
|
+
const valOptions = options && options.formatParams && options.formatParams[options.interpolationkey] || {};
|
|
1608
2110
|
const l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
|
|
1609
2111
|
formatted = this.formats[formatName](mem, l, {
|
|
1610
2112
|
...formatOptions,
|
|
@@ -1631,7 +2133,8 @@ const removePending = (q, name) => {
|
|
|
1631
2133
|
}
|
|
1632
2134
|
};
|
|
1633
2135
|
class Connector extends EventEmitter {
|
|
1634
|
-
constructor(backend, store, services
|
|
2136
|
+
constructor(backend, store, services) {
|
|
2137
|
+
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1635
2138
|
super();
|
|
1636
2139
|
this.backend = backend;
|
|
1637
2140
|
this.store = store;
|
|
@@ -1646,7 +2149,9 @@ class Connector extends EventEmitter {
|
|
|
1646
2149
|
this.retryTimeout = options.retryTimeout >= 1 ? options.retryTimeout : 350;
|
|
1647
2150
|
this.state = {};
|
|
1648
2151
|
this.queue = [];
|
|
1649
|
-
this.backend
|
|
2152
|
+
if (this.backend && this.backend.init) {
|
|
2153
|
+
this.backend.init(services, options.backend, options);
|
|
2154
|
+
}
|
|
1650
2155
|
}
|
|
1651
2156
|
queueLoad(languages, namespaces, options, callback) {
|
|
1652
2157
|
const toLoad = {};
|
|
@@ -1725,7 +2230,10 @@ class Connector extends EventEmitter {
|
|
|
1725
2230
|
this.emit('loaded', loaded);
|
|
1726
2231
|
this.queue = this.queue.filter(q => !q.done);
|
|
1727
2232
|
}
|
|
1728
|
-
read(lng, ns, fcName
|
|
2233
|
+
read(lng, ns, fcName) {
|
|
2234
|
+
let tried = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
2235
|
+
let wait = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.retryTimeout;
|
|
2236
|
+
let callback = arguments.length > 5 ? arguments[5] : undefined;
|
|
1729
2237
|
if (!lng.length) return callback(null, {});
|
|
1730
2238
|
if (this.readingCalls >= this.maxParallelReads) {
|
|
1731
2239
|
this.waitingReads.push({
|
|
@@ -1769,7 +2277,9 @@ class Connector extends EventEmitter {
|
|
|
1769
2277
|
}
|
|
1770
2278
|
return fc(lng, ns, resolver);
|
|
1771
2279
|
}
|
|
1772
|
-
prepareLoading(languages, namespaces
|
|
2280
|
+
prepareLoading(languages, namespaces) {
|
|
2281
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
2282
|
+
let callback = arguments.length > 3 ? arguments[3] : undefined;
|
|
1773
2283
|
if (!this.backend) {
|
|
1774
2284
|
this.logger.warn('No backend was added via i18next.use. Will not load resources.');
|
|
1775
2285
|
return callback && callback();
|
|
@@ -1793,7 +2303,8 @@ class Connector extends EventEmitter {
|
|
|
1793
2303
|
reload: true
|
|
1794
2304
|
}, callback);
|
|
1795
2305
|
}
|
|
1796
|
-
loadOne(name
|
|
2306
|
+
loadOne(name) {
|
|
2307
|
+
let prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
1797
2308
|
const s = name.split('|');
|
|
1798
2309
|
const lng = s[0];
|
|
1799
2310
|
const ns = s[1];
|
|
@@ -1803,13 +2314,15 @@ class Connector extends EventEmitter {
|
|
|
1803
2314
|
this.loaded(name, err, data);
|
|
1804
2315
|
});
|
|
1805
2316
|
}
|
|
1806
|
-
saveMissing(languages, namespace, key, fallbackValue, isUpdate
|
|
1807
|
-
|
|
2317
|
+
saveMissing(languages, namespace, key, fallbackValue, isUpdate) {
|
|
2318
|
+
let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
|
|
2319
|
+
let clb = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : () => {};
|
|
2320
|
+
if (this.services.utils && this.services.utils.hasLoadedNamespace && !this.services.utils.hasLoadedNamespace(namespace)) {
|
|
1808
2321
|
this.logger.warn(`did not save key "${key}" as the namespace "${namespace}" was not yet loaded`, 'This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!');
|
|
1809
2322
|
return;
|
|
1810
2323
|
}
|
|
1811
2324
|
if (key === undefined || key === null || key === '') return;
|
|
1812
|
-
if (this.backend
|
|
2325
|
+
if (this.backend && this.backend.create) {
|
|
1813
2326
|
const opts = {
|
|
1814
2327
|
...options,
|
|
1815
2328
|
isUpdate
|
|
@@ -1842,7 +2355,7 @@ class Connector extends EventEmitter {
|
|
|
1842
2355
|
|
|
1843
2356
|
const get = () => ({
|
|
1844
2357
|
debug: false,
|
|
1845
|
-
|
|
2358
|
+
initImmediate: true,
|
|
1846
2359
|
ns: ['translation'],
|
|
1847
2360
|
defaultNS: ['translation'],
|
|
1848
2361
|
fallbackLng: ['dev'],
|
|
@@ -1898,17 +2411,15 @@ const get = () => ({
|
|
|
1898
2411
|
nestingOptionsSeparator: ',',
|
|
1899
2412
|
maxReplaces: 1000,
|
|
1900
2413
|
skipOnVariables: true
|
|
1901
|
-
}
|
|
1902
|
-
cacheInBuiltFormats: true
|
|
2414
|
+
}
|
|
1903
2415
|
});
|
|
1904
2416
|
const transformOptions = options => {
|
|
1905
2417
|
if (isString(options.ns)) options.ns = [options.ns];
|
|
1906
2418
|
if (isString(options.fallbackLng)) options.fallbackLng = [options.fallbackLng];
|
|
1907
2419
|
if (isString(options.fallbackNS)) options.fallbackNS = [options.fallbackNS];
|
|
1908
|
-
if (options.supportedLngs
|
|
2420
|
+
if (options.supportedLngs && options.supportedLngs.indexOf('cimode') < 0) {
|
|
1909
2421
|
options.supportedLngs = options.supportedLngs.concat(['cimode']);
|
|
1910
2422
|
}
|
|
1911
|
-
if (typeof options.initImmediate === 'boolean') options.initAsync = options.initImmediate;
|
|
1912
2423
|
return options;
|
|
1913
2424
|
};
|
|
1914
2425
|
|
|
@@ -1921,17 +2432,10 @@ const bindMemberFunctions = inst => {
|
|
|
1921
2432
|
}
|
|
1922
2433
|
});
|
|
1923
2434
|
};
|
|
1924
|
-
let supportNoticeShown = false;
|
|
1925
|
-
const usesLocize = inst => {
|
|
1926
|
-
if (inst?.modules?.backend?.name?.indexOf('Locize') > 0) return true;
|
|
1927
|
-
if (inst?.modules?.backend?.constructor?.name?.indexOf('Locize') > 0) return true;
|
|
1928
|
-
if (inst?.options?.backend?.backends) {
|
|
1929
|
-
if (inst.options.backend.backends.some(b => b?.name?.indexOf('Locize') > 0 || b?.constructor?.name?.indexOf('Locize') > 0)) return true;
|
|
1930
|
-
}
|
|
1931
|
-
return false;
|
|
1932
|
-
};
|
|
1933
2435
|
class I18n extends EventEmitter {
|
|
1934
|
-
constructor(
|
|
2436
|
+
constructor() {
|
|
2437
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2438
|
+
let callback = arguments.length > 1 ? arguments[1] : undefined;
|
|
1935
2439
|
super();
|
|
1936
2440
|
this.options = transformOptions(options);
|
|
1937
2441
|
this.services = {};
|
|
@@ -1941,7 +2445,7 @@ class I18n extends EventEmitter {
|
|
|
1941
2445
|
};
|
|
1942
2446
|
bindMemberFunctions(this);
|
|
1943
2447
|
if (callback && !this.isInitialized && !options.isClone) {
|
|
1944
|
-
if (!this.options.
|
|
2448
|
+
if (!this.options.initImmediate) {
|
|
1945
2449
|
this.init(options, callback);
|
|
1946
2450
|
return this;
|
|
1947
2451
|
}
|
|
@@ -1950,13 +2454,16 @@ class I18n extends EventEmitter {
|
|
|
1950
2454
|
}, 0);
|
|
1951
2455
|
}
|
|
1952
2456
|
}
|
|
1953
|
-
init(
|
|
2457
|
+
init() {
|
|
2458
|
+
var _this = this;
|
|
2459
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2460
|
+
let callback = arguments.length > 1 ? arguments[1] : undefined;
|
|
1954
2461
|
this.isInitializing = true;
|
|
1955
2462
|
if (typeof options === 'function') {
|
|
1956
2463
|
callback = options;
|
|
1957
2464
|
options = {};
|
|
1958
2465
|
}
|
|
1959
|
-
if (options.defaultNS
|
|
2466
|
+
if (!options.defaultNS && options.defaultNS !== false && options.ns) {
|
|
1960
2467
|
if (isString(options.ns)) {
|
|
1961
2468
|
options.defaultNS = options.ns;
|
|
1962
2469
|
} else if (options.ns.indexOf('translation') < 0) {
|
|
@@ -1969,23 +2476,18 @@ class I18n extends EventEmitter {
|
|
|
1969
2476
|
...this.options,
|
|
1970
2477
|
...transformOptions(options)
|
|
1971
2478
|
};
|
|
1972
|
-
this.options.
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2479
|
+
if (this.options.compatibilityAPI !== 'v1') {
|
|
2480
|
+
this.options.interpolation = {
|
|
2481
|
+
...defOpts.interpolation,
|
|
2482
|
+
...this.options.interpolation
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
1976
2485
|
if (options.keySeparator !== undefined) {
|
|
1977
2486
|
this.options.userDefinedKeySeparator = options.keySeparator;
|
|
1978
2487
|
}
|
|
1979
2488
|
if (options.nsSeparator !== undefined) {
|
|
1980
2489
|
this.options.userDefinedNsSeparator = options.nsSeparator;
|
|
1981
2490
|
}
|
|
1982
|
-
if (typeof this.options.overloadTranslationOptionHandler !== 'function') {
|
|
1983
|
-
this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
|
|
1984
|
-
}
|
|
1985
|
-
if (this.options.showSupportNotice !== false && !usesLocize(this) && !supportNoticeShown) {
|
|
1986
|
-
if (typeof console !== 'undefined' && typeof console.info !== 'undefined') console.info('🌐 i18next is maintained with support from Locize — consider powering your project with managed localization (AI, CDN, integrations): https://locize.com 💙');
|
|
1987
|
-
supportNoticeShown = true;
|
|
1988
|
-
}
|
|
1989
2491
|
const createClassOnDemand = ClassOrObject => {
|
|
1990
2492
|
if (!ClassOrObject) return null;
|
|
1991
2493
|
if (typeof ClassOrObject === 'function') return new ClassOrObject();
|
|
@@ -2000,7 +2502,7 @@ class I18n extends EventEmitter {
|
|
|
2000
2502
|
let formatter;
|
|
2001
2503
|
if (this.modules.formatter) {
|
|
2002
2504
|
formatter = this.modules.formatter;
|
|
2003
|
-
} else {
|
|
2505
|
+
} else if (typeof Intl !== 'undefined') {
|
|
2004
2506
|
formatter = Formatter;
|
|
2005
2507
|
}
|
|
2006
2508
|
const lu = new LanguageUtil(this.options);
|
|
@@ -2011,15 +2513,12 @@ class I18n extends EventEmitter {
|
|
|
2011
2513
|
s.languageUtils = lu;
|
|
2012
2514
|
s.pluralResolver = new PluralResolver(lu, {
|
|
2013
2515
|
prepend: this.options.pluralSeparator,
|
|
2516
|
+
compatibilityJSON: this.options.compatibilityJSON,
|
|
2014
2517
|
simplifyPluralSuffix: this.options.simplifyPluralSuffix
|
|
2015
2518
|
});
|
|
2016
|
-
const usingLegacyFormatFunction = this.options.interpolation.format && this.options.interpolation.format !== defOpts.interpolation.format;
|
|
2017
|
-
if (usingLegacyFormatFunction) {
|
|
2018
|
-
this.logger.deprecate(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
|
|
2019
|
-
}
|
|
2020
2519
|
if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
|
|
2021
2520
|
s.formatter = createClassOnDemand(formatter);
|
|
2022
|
-
|
|
2521
|
+
s.formatter.init(s, this.options);
|
|
2023
2522
|
this.options.interpolation.format = s.formatter.format.bind(s.formatter);
|
|
2024
2523
|
}
|
|
2025
2524
|
s.interpolator = new Interpolator(this.options);
|
|
@@ -2027,8 +2526,11 @@ class I18n extends EventEmitter {
|
|
|
2027
2526
|
hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
|
|
2028
2527
|
};
|
|
2029
2528
|
s.backendConnector = new Connector(createClassOnDemand(this.modules.backend), s.resourceStore, s, this.options);
|
|
2030
|
-
s.backendConnector.on('*', (event
|
|
2031
|
-
|
|
2529
|
+
s.backendConnector.on('*', function (event) {
|
|
2530
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
2531
|
+
args[_key - 1] = arguments[_key];
|
|
2532
|
+
}
|
|
2533
|
+
_this.emit(event, ...args);
|
|
2032
2534
|
});
|
|
2033
2535
|
if (this.modules.languageDetector) {
|
|
2034
2536
|
s.languageDetector = createClassOnDemand(this.modules.languageDetector);
|
|
@@ -2039,8 +2541,11 @@ class I18n extends EventEmitter {
|
|
|
2039
2541
|
if (s.i18nFormat.init) s.i18nFormat.init(this);
|
|
2040
2542
|
}
|
|
2041
2543
|
this.translator = new Translator(this.services, this.options);
|
|
2042
|
-
this.translator.on('*', (event
|
|
2043
|
-
|
|
2544
|
+
this.translator.on('*', function (event) {
|
|
2545
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
2546
|
+
args[_key2 - 1] = arguments[_key2];
|
|
2547
|
+
}
|
|
2548
|
+
_this.emit(event, ...args);
|
|
2044
2549
|
});
|
|
2045
2550
|
this.modules.external.forEach(m => {
|
|
2046
2551
|
if (m.init) m.init(this);
|
|
@@ -2057,13 +2562,15 @@ class I18n extends EventEmitter {
|
|
|
2057
2562
|
}
|
|
2058
2563
|
const storeApi = ['getResource', 'hasResourceBundle', 'getResourceBundle', 'getDataByLanguage'];
|
|
2059
2564
|
storeApi.forEach(fcName => {
|
|
2060
|
-
this[fcName] = (
|
|
2565
|
+
this[fcName] = function () {
|
|
2566
|
+
return _this.store[fcName](...arguments);
|
|
2567
|
+
};
|
|
2061
2568
|
});
|
|
2062
2569
|
const storeApiChained = ['addResource', 'addResources', 'addResourceBundle', 'removeResourceBundle'];
|
|
2063
2570
|
storeApiChained.forEach(fcName => {
|
|
2064
|
-
this[fcName] = (
|
|
2065
|
-
|
|
2066
|
-
return
|
|
2571
|
+
this[fcName] = function () {
|
|
2572
|
+
_this.store[fcName](...arguments);
|
|
2573
|
+
return _this;
|
|
2067
2574
|
};
|
|
2068
2575
|
});
|
|
2069
2576
|
const deferred = defer();
|
|
@@ -2077,22 +2584,23 @@ class I18n extends EventEmitter {
|
|
|
2077
2584
|
deferred.resolve(t);
|
|
2078
2585
|
callback(err, t);
|
|
2079
2586
|
};
|
|
2080
|
-
if (this.languages && !this.isInitialized) return finish(null, this.t.bind(this));
|
|
2587
|
+
if (this.languages && this.options.compatibilityAPI !== 'v1' && !this.isInitialized) return finish(null, this.t.bind(this));
|
|
2081
2588
|
this.changeLanguage(this.options.lng, finish);
|
|
2082
2589
|
};
|
|
2083
|
-
if (this.options.resources || !this.options.
|
|
2590
|
+
if (this.options.resources || !this.options.initImmediate) {
|
|
2084
2591
|
load();
|
|
2085
2592
|
} else {
|
|
2086
2593
|
setTimeout(load, 0);
|
|
2087
2594
|
}
|
|
2088
2595
|
return deferred;
|
|
2089
2596
|
}
|
|
2090
|
-
loadResources(language
|
|
2597
|
+
loadResources(language) {
|
|
2598
|
+
let callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
|
|
2091
2599
|
let usedCallback = callback;
|
|
2092
2600
|
const usedLng = isString(language) ? language : this.language;
|
|
2093
2601
|
if (typeof language === 'function') usedCallback = language;
|
|
2094
2602
|
if (!this.options.resources || this.options.partialBundledLanguages) {
|
|
2095
|
-
if (usedLng
|
|
2603
|
+
if (usedLng && usedLng.toLowerCase() === 'cimode' && (!this.options.preload || this.options.preload.length === 0)) return usedCallback();
|
|
2096
2604
|
const toLoad = [];
|
|
2097
2605
|
const append = lng => {
|
|
2098
2606
|
if (!lng) return;
|
|
@@ -2109,7 +2617,9 @@ class I18n extends EventEmitter {
|
|
|
2109
2617
|
} else {
|
|
2110
2618
|
append(usedLng);
|
|
2111
2619
|
}
|
|
2112
|
-
this.options.preload
|
|
2620
|
+
if (this.options.preload) {
|
|
2621
|
+
this.options.preload.forEach(l => append(l));
|
|
2622
|
+
}
|
|
2113
2623
|
this.services.backendConnector.load(toLoad, this.options.ns, e => {
|
|
2114
2624
|
if (!e && !this.resolvedLanguage && this.language) this.setResolvedLanguage(this.language);
|
|
2115
2625
|
usedCallback(e);
|
|
@@ -2174,542 +2684,249 @@ class I18n extends EventEmitter {
|
|
|
2174
2684
|
break;
|
|
2175
2685
|
}
|
|
2176
2686
|
}
|
|
2177
|
-
if (!this.resolvedLanguage && this.languages.indexOf(l) < 0 && this.store.hasLanguageSomeTranslations(l)) {
|
|
2178
|
-
this.resolvedLanguage = l;
|
|
2179
|
-
this.languages.unshift(l);
|
|
2180
|
-
}
|
|
2181
2687
|
}
|
|
2182
2688
|
changeLanguage(lng, callback) {
|
|
2689
|
+
var _this2 = this;
|
|
2183
2690
|
this.isLanguageChangingTo = lng;
|
|
2184
2691
|
const deferred = defer();
|
|
2185
2692
|
this.emit('languageChanging', lng);
|
|
2186
|
-
const setLngProps = l => {
|
|
2187
|
-
this.language = l;
|
|
2188
|
-
this.languages = this.services.languageUtils.toResolveHierarchy(l);
|
|
2189
|
-
this.resolvedLanguage = undefined;
|
|
2190
|
-
this.setResolvedLanguage(l);
|
|
2191
|
-
};
|
|
2192
|
-
const done = (err, l) => {
|
|
2193
|
-
if (l) {
|
|
2194
|
-
if (this.isLanguageChangingTo === lng) {
|
|
2195
|
-
setLngProps(l);
|
|
2196
|
-
this.translator.changeLanguage(l);
|
|
2197
|
-
this.isLanguageChangingTo = undefined;
|
|
2198
|
-
this.emit('languageChanged', l);
|
|
2199
|
-
this.logger.log('languageChanged', l);
|
|
2200
|
-
}
|
|
2201
|
-
} else {
|
|
2202
|
-
this.isLanguageChangingTo = undefined;
|
|
2203
|
-
}
|
|
2204
|
-
deferred.resolve((...args) => this.t(...args));
|
|
2205
|
-
if (callback) callback(err, (...args) => this.t(...args));
|
|
2206
|
-
};
|
|
2207
|
-
const setLng = lngs => {
|
|
2208
|
-
if (!lng && !lngs && this.services.languageDetector) lngs = [];
|
|
2209
|
-
const fl = isString(lngs) ? lngs : lngs && lngs[0];
|
|
2210
|
-
const l = this.store.hasLanguageSomeTranslations(fl) ? fl : this.services.languageUtils.getBestMatchFromCodes(isString(lngs) ? [lngs] : lngs);
|
|
2211
|
-
if (l) {
|
|
2212
|
-
if (!this.language) {
|
|
2213
|
-
setLngProps(l);
|
|
2214
|
-
}
|
|
2215
|
-
if (!this.translator.language) this.translator.changeLanguage(l);
|
|
2216
|
-
this.services.languageDetector?.cacheUserLanguage?.(l);
|
|
2217
|
-
}
|
|
2218
|
-
this.loadResources(l, err => {
|
|
2219
|
-
done(err, l);
|
|
2220
|
-
});
|
|
2221
|
-
};
|
|
2222
|
-
if (!lng && this.services.languageDetector && !this.services.languageDetector.async) {
|
|
2223
|
-
setLng(this.services.languageDetector.detect());
|
|
2224
|
-
} else if (!lng && this.services.languageDetector && this.services.languageDetector.async) {
|
|
2225
|
-
if (this.services.languageDetector.detect.length === 0) {
|
|
2226
|
-
this.services.languageDetector.detect().then(setLng);
|
|
2227
|
-
} else {
|
|
2228
|
-
this.services.languageDetector.detect(setLng);
|
|
2229
|
-
}
|
|
2230
|
-
} else {
|
|
2231
|
-
setLng(lng);
|
|
2232
|
-
}
|
|
2233
|
-
return deferred;
|
|
2234
|
-
}
|
|
2235
|
-
getFixedT(lng, ns, keyPrefix) {
|
|
2236
|
-
const fixedT = (key, opts, ...rest) => {
|
|
2237
|
-
let o;
|
|
2238
|
-
if (typeof opts !== 'object') {
|
|
2239
|
-
o = this.options.overloadTranslationOptionHandler([key, opts].concat(rest));
|
|
2240
|
-
} else {
|
|
2241
|
-
o = {
|
|
2242
|
-
...opts
|
|
2243
|
-
};
|
|
2244
|
-
}
|
|
2245
|
-
o.lng = o.lng || fixedT.lng;
|
|
2246
|
-
o.lngs = o.lngs || fixedT.lngs;
|
|
2247
|
-
o.ns = o.ns || fixedT.ns;
|
|
2248
|
-
if (o.keyPrefix !== '') o.keyPrefix = o.keyPrefix || keyPrefix || fixedT.keyPrefix;
|
|
2249
|
-
const keySeparator = this.options.keySeparator || '.';
|
|
2250
|
-
let resultKey;
|
|
2251
|
-
if (o.keyPrefix && Array.isArray(key)) {
|
|
2252
|
-
resultKey = key.map(k => {
|
|
2253
|
-
if (typeof k === 'function') k = keysFromSelector(k, {
|
|
2254
|
-
...this.options,
|
|
2255
|
-
...opts
|
|
2256
|
-
});
|
|
2257
|
-
return `${o.keyPrefix}${keySeparator}${k}`;
|
|
2258
|
-
});
|
|
2259
|
-
} else {
|
|
2260
|
-
if (typeof key === 'function') key = keysFromSelector(key, {
|
|
2261
|
-
...this.options,
|
|
2262
|
-
...opts
|
|
2263
|
-
});
|
|
2264
|
-
resultKey = o.keyPrefix ? `${o.keyPrefix}${keySeparator}${key}` : key;
|
|
2265
|
-
}
|
|
2266
|
-
return this.t(resultKey, o);
|
|
2267
|
-
};
|
|
2268
|
-
if (isString(lng)) {
|
|
2269
|
-
fixedT.lng = lng;
|
|
2270
|
-
} else {
|
|
2271
|
-
fixedT.lngs = lng;
|
|
2272
|
-
}
|
|
2273
|
-
fixedT.ns = ns;
|
|
2274
|
-
fixedT.keyPrefix = keyPrefix;
|
|
2275
|
-
return fixedT;
|
|
2276
|
-
}
|
|
2277
|
-
t(...args) {
|
|
2278
|
-
return this.translator?.translate(...args);
|
|
2279
|
-
}
|
|
2280
|
-
exists(...args) {
|
|
2281
|
-
return this.translator?.exists(...args);
|
|
2282
|
-
}
|
|
2283
|
-
setDefaultNamespace(ns) {
|
|
2284
|
-
this.options.defaultNS = ns;
|
|
2285
|
-
}
|
|
2286
|
-
hasLoadedNamespace(ns, options = {}) {
|
|
2287
|
-
if (!this.isInitialized) {
|
|
2288
|
-
this.logger.warn('hasLoadedNamespace: i18next was not initialized', this.languages);
|
|
2289
|
-
return false;
|
|
2290
|
-
}
|
|
2291
|
-
if (!this.languages || !this.languages.length) {
|
|
2292
|
-
this.logger.warn('hasLoadedNamespace: i18n.languages were undefined or empty', this.languages);
|
|
2293
|
-
return false;
|
|
2294
|
-
}
|
|
2295
|
-
const lng = options.lng || this.resolvedLanguage || this.languages[0];
|
|
2296
|
-
const fallbackLng = this.options ? this.options.fallbackLng : false;
|
|
2297
|
-
const lastLng = this.languages[this.languages.length - 1];
|
|
2298
|
-
if (lng.toLowerCase() === 'cimode') return true;
|
|
2299
|
-
const loadNotPending = (l, n) => {
|
|
2300
|
-
const loadState = this.services.backendConnector.state[`${l}|${n}`];
|
|
2301
|
-
return loadState === -1 || loadState === 0 || loadState === 2;
|
|
2302
|
-
};
|
|
2303
|
-
if (options.precheck) {
|
|
2304
|
-
const preResult = options.precheck(this, loadNotPending);
|
|
2305
|
-
if (preResult !== undefined) return preResult;
|
|
2306
|
-
}
|
|
2307
|
-
if (this.hasResourceBundle(lng, ns)) return true;
|
|
2308
|
-
if (!this.services.backendConnector.backend || this.options.resources && !this.options.partialBundledLanguages) return true;
|
|
2309
|
-
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
|
|
2310
|
-
return false;
|
|
2311
|
-
}
|
|
2312
|
-
loadNamespaces(ns, callback) {
|
|
2313
|
-
const deferred = defer();
|
|
2314
|
-
if (!this.options.ns) {
|
|
2315
|
-
if (callback) callback();
|
|
2316
|
-
return Promise.resolve();
|
|
2317
|
-
}
|
|
2318
|
-
if (isString(ns)) ns = [ns];
|
|
2319
|
-
ns.forEach(n => {
|
|
2320
|
-
if (this.options.ns.indexOf(n) < 0) this.options.ns.push(n);
|
|
2321
|
-
});
|
|
2322
|
-
this.loadResources(err => {
|
|
2323
|
-
deferred.resolve();
|
|
2324
|
-
if (callback) callback(err);
|
|
2325
|
-
});
|
|
2326
|
-
return deferred;
|
|
2327
|
-
}
|
|
2328
|
-
loadLanguages(lngs, callback) {
|
|
2329
|
-
const deferred = defer();
|
|
2330
|
-
if (isString(lngs)) lngs = [lngs];
|
|
2331
|
-
const preloaded = this.options.preload || [];
|
|
2332
|
-
const newLngs = lngs.filter(lng => preloaded.indexOf(lng) < 0 && this.services.languageUtils.isSupportedCode(lng));
|
|
2333
|
-
if (!newLngs.length) {
|
|
2334
|
-
if (callback) callback();
|
|
2335
|
-
return Promise.resolve();
|
|
2336
|
-
}
|
|
2337
|
-
this.options.preload = preloaded.concat(newLngs);
|
|
2338
|
-
this.loadResources(err => {
|
|
2339
|
-
deferred.resolve();
|
|
2340
|
-
if (callback) callback(err);
|
|
2341
|
-
});
|
|
2342
|
-
return deferred;
|
|
2343
|
-
}
|
|
2344
|
-
dir(lng) {
|
|
2345
|
-
if (!lng) lng = this.resolvedLanguage || (this.languages?.length > 0 ? this.languages[0] : this.language);
|
|
2346
|
-
if (!lng) return 'rtl';
|
|
2347
|
-
try {
|
|
2348
|
-
const l = new Intl.Locale(lng);
|
|
2349
|
-
if (l && l.getTextInfo) {
|
|
2350
|
-
const ti = l.getTextInfo();
|
|
2351
|
-
if (ti && ti.direction) return ti.direction;
|
|
2352
|
-
}
|
|
2353
|
-
} catch (e) {}
|
|
2354
|
-
const rtlLngs = ['ar', 'shu', 'sqr', 'ssh', 'xaa', 'yhd', 'yud', 'aao', 'abh', 'abv', 'acm', 'acq', 'acw', 'acx', 'acy', 'adf', 'ads', 'aeb', 'aec', 'afb', 'ajp', 'apc', 'apd', 'arb', 'arq', 'ars', 'ary', 'arz', 'auz', 'avl', 'ayh', 'ayl', 'ayn', 'ayp', 'bbz', 'pga', 'he', 'iw', 'ps', 'pbt', 'pbu', 'pst', 'prp', 'prd', 'ug', 'ur', 'ydd', 'yds', 'yih', 'ji', 'yi', 'hbo', 'men', 'xmn', 'fa', 'jpr', 'peo', 'pes', 'prs', 'dv', 'sam', 'ckb'];
|
|
2355
|
-
const languageUtils = this.services?.languageUtils || new LanguageUtil(get());
|
|
2356
|
-
if (lng.toLowerCase().indexOf('-latn') > 1) return 'ltr';
|
|
2357
|
-
return rtlLngs.indexOf(languageUtils.getLanguagePartFromCode(lng)) > -1 || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
|
|
2358
|
-
}
|
|
2359
|
-
static createInstance(options = {}, callback) {
|
|
2360
|
-
const instance = new I18n(options, callback);
|
|
2361
|
-
instance.createInstance = I18n.createInstance;
|
|
2362
|
-
return instance;
|
|
2363
|
-
}
|
|
2364
|
-
cloneInstance(options = {}, callback = noop) {
|
|
2365
|
-
const forkResourceStore = options.forkResourceStore;
|
|
2366
|
-
if (forkResourceStore) delete options.forkResourceStore;
|
|
2367
|
-
const mergedOptions = {
|
|
2368
|
-
...this.options,
|
|
2369
|
-
...options,
|
|
2370
|
-
...{
|
|
2371
|
-
isClone: true
|
|
2372
|
-
}
|
|
2693
|
+
const setLngProps = l => {
|
|
2694
|
+
this.language = l;
|
|
2695
|
+
this.languages = this.services.languageUtils.toResolveHierarchy(l);
|
|
2696
|
+
this.resolvedLanguage = undefined;
|
|
2697
|
+
this.setResolvedLanguage(l);
|
|
2373
2698
|
};
|
|
2374
|
-
const
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2699
|
+
const done = (err, l) => {
|
|
2700
|
+
if (l) {
|
|
2701
|
+
setLngProps(l);
|
|
2702
|
+
this.translator.changeLanguage(l);
|
|
2703
|
+
this.isLanguageChangingTo = undefined;
|
|
2704
|
+
this.emit('languageChanged', l);
|
|
2705
|
+
this.logger.log('languageChanged', l);
|
|
2706
|
+
} else {
|
|
2707
|
+
this.isLanguageChangingTo = undefined;
|
|
2708
|
+
}
|
|
2709
|
+
deferred.resolve(function () {
|
|
2710
|
+
return _this2.t(...arguments);
|
|
2711
|
+
});
|
|
2712
|
+
if (callback) callback(err, function () {
|
|
2713
|
+
return _this2.t(...arguments);
|
|
2714
|
+
});
|
|
2384
2715
|
};
|
|
2385
|
-
|
|
2386
|
-
|
|
2716
|
+
const setLng = lngs => {
|
|
2717
|
+
if (!lng && !lngs && this.services.languageDetector) lngs = [];
|
|
2718
|
+
const l = isString(lngs) ? lngs : this.services.languageUtils.getBestMatchFromCodes(lngs);
|
|
2719
|
+
if (l) {
|
|
2720
|
+
if (!this.language) {
|
|
2721
|
+
setLngProps(l);
|
|
2722
|
+
}
|
|
2723
|
+
if (!this.translator.language) this.translator.changeLanguage(l);
|
|
2724
|
+
if (this.services.languageDetector && this.services.languageDetector.cacheUserLanguage) this.services.languageDetector.cacheUserLanguage(l);
|
|
2725
|
+
}
|
|
2726
|
+
this.loadResources(l, err => {
|
|
2727
|
+
done(err, l);
|
|
2728
|
+
});
|
|
2387
2729
|
};
|
|
2388
|
-
if (
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
}, prev[l]);
|
|
2399
|
-
return prev;
|
|
2400
|
-
}, {});
|
|
2401
|
-
clone.store = new ResourceStore(clonedData, mergedOptions);
|
|
2402
|
-
clone.services.resourceStore = clone.store;
|
|
2403
|
-
}
|
|
2404
|
-
if (options.interpolation) {
|
|
2405
|
-
const defOpts = get();
|
|
2406
|
-
const mergedInterpolation = {
|
|
2407
|
-
...defOpts.interpolation,
|
|
2408
|
-
...this.options.interpolation,
|
|
2409
|
-
...options.interpolation
|
|
2410
|
-
};
|
|
2411
|
-
const mergedForInterpolator = {
|
|
2412
|
-
...mergedOptions,
|
|
2413
|
-
interpolation: mergedInterpolation
|
|
2414
|
-
};
|
|
2415
|
-
clone.services.interpolator = new Interpolator(mergedForInterpolator);
|
|
2730
|
+
if (!lng && this.services.languageDetector && !this.services.languageDetector.async) {
|
|
2731
|
+
setLng(this.services.languageDetector.detect());
|
|
2732
|
+
} else if (!lng && this.services.languageDetector && this.services.languageDetector.async) {
|
|
2733
|
+
if (this.services.languageDetector.detect.length === 0) {
|
|
2734
|
+
this.services.languageDetector.detect().then(setLng);
|
|
2735
|
+
} else {
|
|
2736
|
+
this.services.languageDetector.detect(setLng);
|
|
2737
|
+
}
|
|
2738
|
+
} else {
|
|
2739
|
+
setLng(lng);
|
|
2416
2740
|
}
|
|
2417
|
-
|
|
2418
|
-
clone.translator.on('*', (event, ...args) => {
|
|
2419
|
-
clone.emit(event, ...args);
|
|
2420
|
-
});
|
|
2421
|
-
clone.init(mergedOptions, callback);
|
|
2422
|
-
clone.translator.options = mergedOptions;
|
|
2423
|
-
clone.translator.backendConnector.services.utils = {
|
|
2424
|
-
hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
|
|
2425
|
-
};
|
|
2426
|
-
return clone;
|
|
2741
|
+
return deferred;
|
|
2427
2742
|
}
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2743
|
+
getFixedT(lng, ns, keyPrefix) {
|
|
2744
|
+
var _this3 = this;
|
|
2745
|
+
const fixedT = function (key, opts) {
|
|
2746
|
+
let options;
|
|
2747
|
+
if (typeof opts !== 'object') {
|
|
2748
|
+
for (var _len3 = arguments.length, rest = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) {
|
|
2749
|
+
rest[_key3 - 2] = arguments[_key3];
|
|
2750
|
+
}
|
|
2751
|
+
options = _this3.options.overloadTranslationOptionHandler([key, opts].concat(rest));
|
|
2752
|
+
} else {
|
|
2753
|
+
options = {
|
|
2754
|
+
...opts
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2757
|
+
options.lng = options.lng || fixedT.lng;
|
|
2758
|
+
options.lngs = options.lngs || fixedT.lngs;
|
|
2759
|
+
options.ns = options.ns || fixedT.ns;
|
|
2760
|
+
if (options.keyPrefix !== '') options.keyPrefix = options.keyPrefix || keyPrefix || fixedT.keyPrefix;
|
|
2761
|
+
const keySeparator = _this3.options.keySeparator || '.';
|
|
2762
|
+
let resultKey;
|
|
2763
|
+
if (options.keyPrefix && Array.isArray(key)) {
|
|
2764
|
+
resultKey = key.map(k => `${options.keyPrefix}${keySeparator}${k}`);
|
|
2765
|
+
} else {
|
|
2766
|
+
resultKey = options.keyPrefix ? `${options.keyPrefix}${keySeparator}${key}` : key;
|
|
2767
|
+
}
|
|
2768
|
+
return _this3.t(resultKey, options);
|
|
2435
2769
|
};
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
instance.createInstance;
|
|
2441
|
-
instance.dir;
|
|
2442
|
-
instance.init;
|
|
2443
|
-
instance.loadResources;
|
|
2444
|
-
instance.reloadResources;
|
|
2445
|
-
instance.use;
|
|
2446
|
-
instance.changeLanguage;
|
|
2447
|
-
instance.getFixedT;
|
|
2448
|
-
instance.t;
|
|
2449
|
-
instance.exists;
|
|
2450
|
-
instance.setDefaultNamespace;
|
|
2451
|
-
instance.hasLoadedNamespace;
|
|
2452
|
-
instance.loadNamespaces;
|
|
2453
|
-
instance.loadLanguages;
|
|
2454
|
-
|
|
2455
|
-
function warn() {
|
|
2456
|
-
if (console && console.warn) {
|
|
2457
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
2458
|
-
args[_key] = arguments[_key];
|
|
2770
|
+
if (isString(lng)) {
|
|
2771
|
+
fixedT.lng = lng;
|
|
2772
|
+
} else {
|
|
2773
|
+
fixedT.lngs = lng;
|
|
2459
2774
|
}
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
}
|
|
2464
|
-
const alreadyWarned = {};
|
|
2465
|
-
function warnOnce() {
|
|
2466
|
-
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
2467
|
-
args[_key2] = arguments[_key2];
|
|
2775
|
+
fixedT.ns = ns;
|
|
2776
|
+
fixedT.keyPrefix = keyPrefix;
|
|
2777
|
+
return fixedT;
|
|
2468
2778
|
}
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
warn(...args);
|
|
2472
|
-
}
|
|
2473
|
-
const loadedClb = (i18n, cb) => () => {
|
|
2474
|
-
if (i18n.isInitialized) {
|
|
2475
|
-
cb();
|
|
2476
|
-
} else {
|
|
2477
|
-
const initialized = () => {
|
|
2478
|
-
setTimeout(() => {
|
|
2479
|
-
i18n.off('initialized', initialized);
|
|
2480
|
-
}, 0);
|
|
2481
|
-
cb();
|
|
2482
|
-
};
|
|
2483
|
-
i18n.on('initialized', initialized);
|
|
2779
|
+
t() {
|
|
2780
|
+
return this.translator && this.translator.translate(...arguments);
|
|
2484
2781
|
}
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
i18n.loadNamespaces(ns, loadedClb(i18n, cb));
|
|
2488
|
-
}
|
|
2489
|
-
function loadLanguages(i18n, lng, ns, cb) {
|
|
2490
|
-
if (typeof ns === 'string') ns = [ns];
|
|
2491
|
-
ns.forEach(n => {
|
|
2492
|
-
if (i18n.options.ns.indexOf(n) < 0) i18n.options.ns.push(n);
|
|
2493
|
-
});
|
|
2494
|
-
i18n.loadLanguages(lng, loadedClb(i18n, cb));
|
|
2495
|
-
}
|
|
2496
|
-
function oldI18nextHasLoadedNamespace(ns, i18n) {
|
|
2497
|
-
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
2498
|
-
const lng = i18n.languages[0];
|
|
2499
|
-
const fallbackLng = i18n.options ? i18n.options.fallbackLng : false;
|
|
2500
|
-
const lastLng = i18n.languages[i18n.languages.length - 1];
|
|
2501
|
-
if (lng.toLowerCase() === 'cimode') return true;
|
|
2502
|
-
const loadNotPending = (l, n) => {
|
|
2503
|
-
const loadState = i18n.services.backendConnector.state[`${l}|${n}`];
|
|
2504
|
-
return loadState === -1 || loadState === 2;
|
|
2505
|
-
};
|
|
2506
|
-
if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18n.services.backendConnector.backend && i18n.isLanguageChangingTo && !loadNotPending(i18n.isLanguageChangingTo, ns)) return false;
|
|
2507
|
-
if (i18n.hasResourceBundle(lng, ns)) return true;
|
|
2508
|
-
if (!i18n.services.backendConnector.backend || i18n.options.resources && !i18n.options.partialBundledLanguages) return true;
|
|
2509
|
-
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
|
|
2510
|
-
return false;
|
|
2511
|
-
}
|
|
2512
|
-
function hasLoadedNamespace(ns, i18n) {
|
|
2513
|
-
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
2514
|
-
if (!i18n.languages || !i18n.languages.length) {
|
|
2515
|
-
warnOnce('i18n.languages were undefined or empty', i18n.languages);
|
|
2516
|
-
return true;
|
|
2782
|
+
exists() {
|
|
2783
|
+
return this.translator && this.translator.exists(...arguments);
|
|
2517
2784
|
}
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
return oldI18nextHasLoadedNamespace(ns, i18n, options);
|
|
2785
|
+
setDefaultNamespace(ns) {
|
|
2786
|
+
this.options.defaultNS = ns;
|
|
2521
2787
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2788
|
+
hasLoadedNamespace(ns) {
|
|
2789
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
2790
|
+
if (!this.isInitialized) {
|
|
2791
|
+
this.logger.warn('hasLoadedNamespace: i18next was not initialized', this.languages);
|
|
2792
|
+
return false;
|
|
2526
2793
|
}
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
const
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
'®': '®',
|
|
2548
|
-
'…': '…',
|
|
2549
|
-
'…': '…',
|
|
2550
|
-
'/': '/',
|
|
2551
|
-
'/': '/'
|
|
2552
|
-
};
|
|
2553
|
-
const unescapeHtmlEntity = m => htmlEntities[m];
|
|
2554
|
-
const unescape = text => text.replace(matchHtmlEntity, unescapeHtmlEntity);
|
|
2555
|
-
|
|
2556
|
-
let defaultOptions$1 = {
|
|
2557
|
-
bindI18n: 'languageChanged',
|
|
2558
|
-
bindI18nStore: '',
|
|
2559
|
-
transEmptyNodeValue: '',
|
|
2560
|
-
transSupportBasicHtmlNodes: true,
|
|
2561
|
-
transWrapTextNodes: '',
|
|
2562
|
-
transKeepBasicHtmlNodesFor: ['br', 'strong', 'i', 'p'],
|
|
2563
|
-
useSuspense: true,
|
|
2564
|
-
unescape
|
|
2565
|
-
};
|
|
2566
|
-
function setDefaults() {
|
|
2567
|
-
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2568
|
-
defaultOptions$1 = {
|
|
2569
|
-
...defaultOptions$1,
|
|
2570
|
-
...options
|
|
2571
|
-
};
|
|
2572
|
-
}
|
|
2573
|
-
function getDefaults() {
|
|
2574
|
-
return defaultOptions$1;
|
|
2575
|
-
}
|
|
2576
|
-
|
|
2577
|
-
let i18nInstance;
|
|
2578
|
-
function setI18n(instance) {
|
|
2579
|
-
i18nInstance = instance;
|
|
2580
|
-
}
|
|
2581
|
-
function getI18n() {
|
|
2582
|
-
return i18nInstance;
|
|
2583
|
-
}
|
|
2584
|
-
|
|
2585
|
-
const initReactI18next = {
|
|
2586
|
-
type: '3rdParty',
|
|
2587
|
-
init(instance) {
|
|
2588
|
-
setDefaults(instance.options.react);
|
|
2589
|
-
setI18n(instance);
|
|
2590
|
-
}
|
|
2591
|
-
};
|
|
2592
|
-
|
|
2593
|
-
const I18nContext = createContext();
|
|
2594
|
-
class ReportNamespaces {
|
|
2595
|
-
constructor() {
|
|
2596
|
-
this.usedNamespaces = {};
|
|
2794
|
+
if (!this.languages || !this.languages.length) {
|
|
2795
|
+
this.logger.warn('hasLoadedNamespace: i18n.languages were undefined or empty', this.languages);
|
|
2796
|
+
return false;
|
|
2797
|
+
}
|
|
2798
|
+
const lng = options.lng || this.resolvedLanguage || this.languages[0];
|
|
2799
|
+
const fallbackLng = this.options ? this.options.fallbackLng : false;
|
|
2800
|
+
const lastLng = this.languages[this.languages.length - 1];
|
|
2801
|
+
if (lng.toLowerCase() === 'cimode') return true;
|
|
2802
|
+
const loadNotPending = (l, n) => {
|
|
2803
|
+
const loadState = this.services.backendConnector.state[`${l}|${n}`];
|
|
2804
|
+
return loadState === -1 || loadState === 0 || loadState === 2;
|
|
2805
|
+
};
|
|
2806
|
+
if (options.precheck) {
|
|
2807
|
+
const preResult = options.precheck(this, loadNotPending);
|
|
2808
|
+
if (preResult !== undefined) return preResult;
|
|
2809
|
+
}
|
|
2810
|
+
if (this.hasResourceBundle(lng, ns)) return true;
|
|
2811
|
+
if (!this.services.backendConnector.backend || this.options.resources && !this.options.partialBundledLanguages) return true;
|
|
2812
|
+
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
|
|
2813
|
+
return false;
|
|
2597
2814
|
}
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2815
|
+
loadNamespaces(ns, callback) {
|
|
2816
|
+
const deferred = defer();
|
|
2817
|
+
if (!this.options.ns) {
|
|
2818
|
+
if (callback) callback();
|
|
2819
|
+
return Promise.resolve();
|
|
2820
|
+
}
|
|
2821
|
+
if (isString(ns)) ns = [ns];
|
|
2822
|
+
ns.forEach(n => {
|
|
2823
|
+
if (this.options.ns.indexOf(n) < 0) this.options.ns.push(n);
|
|
2601
2824
|
});
|
|
2825
|
+
this.loadResources(err => {
|
|
2826
|
+
deferred.resolve();
|
|
2827
|
+
if (callback) callback(err);
|
|
2828
|
+
});
|
|
2829
|
+
return deferred;
|
|
2602
2830
|
}
|
|
2603
|
-
|
|
2604
|
-
|
|
2831
|
+
loadLanguages(lngs, callback) {
|
|
2832
|
+
const deferred = defer();
|
|
2833
|
+
if (isString(lngs)) lngs = [lngs];
|
|
2834
|
+
const preloaded = this.options.preload || [];
|
|
2835
|
+
const newLngs = lngs.filter(lng => preloaded.indexOf(lng) < 0 && this.services.languageUtils.isSupportedCode(lng));
|
|
2836
|
+
if (!newLngs.length) {
|
|
2837
|
+
if (callback) callback();
|
|
2838
|
+
return Promise.resolve();
|
|
2839
|
+
}
|
|
2840
|
+
this.options.preload = preloaded.concat(newLngs);
|
|
2841
|
+
this.loadResources(err => {
|
|
2842
|
+
deferred.resolve();
|
|
2843
|
+
if (callback) callback(err);
|
|
2844
|
+
});
|
|
2845
|
+
return deferred;
|
|
2605
2846
|
}
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
}, [value, ignore]);
|
|
2613
|
-
return ref.current;
|
|
2614
|
-
};
|
|
2615
|
-
function useTranslation(ns) {
|
|
2616
|
-
let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
2617
|
-
const {
|
|
2618
|
-
i18n: i18nFromProps
|
|
2619
|
-
} = props;
|
|
2620
|
-
const {
|
|
2621
|
-
i18n: i18nFromContext,
|
|
2622
|
-
defaultNS: defaultNSFromContext
|
|
2623
|
-
} = useContext(I18nContext) || {};
|
|
2624
|
-
const i18n = i18nFromProps || i18nFromContext || getI18n();
|
|
2625
|
-
if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces();
|
|
2626
|
-
if (!i18n) {
|
|
2627
|
-
warnOnce('You will need to pass in an i18next instance by using initReactI18next');
|
|
2628
|
-
const notReadyT = (k, optsOrDefaultValue) => {
|
|
2629
|
-
if (typeof optsOrDefaultValue === 'string') return optsOrDefaultValue;
|
|
2630
|
-
if (optsOrDefaultValue && typeof optsOrDefaultValue === 'object' && typeof optsOrDefaultValue.defaultValue === 'string') return optsOrDefaultValue.defaultValue;
|
|
2631
|
-
return Array.isArray(k) ? k[k.length - 1] : k;
|
|
2632
|
-
};
|
|
2633
|
-
const retNotReady = [notReadyT, {}, false];
|
|
2634
|
-
retNotReady.t = notReadyT;
|
|
2635
|
-
retNotReady.i18n = {};
|
|
2636
|
-
retNotReady.ready = false;
|
|
2637
|
-
return retNotReady;
|
|
2847
|
+
dir(lng) {
|
|
2848
|
+
if (!lng) lng = this.resolvedLanguage || (this.languages && this.languages.length > 0 ? this.languages[0] : this.language);
|
|
2849
|
+
if (!lng) return 'rtl';
|
|
2850
|
+
const rtlLngs = ['ar', 'shu', 'sqr', 'ssh', 'xaa', 'yhd', 'yud', 'aao', 'abh', 'abv', 'acm', 'acq', 'acw', 'acx', 'acy', 'adf', 'ads', 'aeb', 'aec', 'afb', 'ajp', 'apc', 'apd', 'arb', 'arq', 'ars', 'ary', 'arz', 'auz', 'avl', 'ayh', 'ayl', 'ayn', 'ayp', 'bbz', 'pga', 'he', 'iw', 'ps', 'pbt', 'pbu', 'pst', 'prp', 'prd', 'ug', 'ur', 'ydd', 'yds', 'yih', 'ji', 'yi', 'hbo', 'men', 'xmn', 'fa', 'jpr', 'peo', 'pes', 'prs', 'dv', 'sam', 'ckb'];
|
|
2851
|
+
const languageUtils = this.services && this.services.languageUtils || new LanguageUtil(get());
|
|
2852
|
+
return rtlLngs.indexOf(languageUtils.getLanguagePartFromCode(lng)) > -1 || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
|
|
2638
2853
|
}
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
...props
|
|
2644
|
-
};
|
|
2645
|
-
const {
|
|
2646
|
-
useSuspense,
|
|
2647
|
-
keyPrefix
|
|
2648
|
-
} = i18nOptions;
|
|
2649
|
-
let namespaces = ns || defaultNSFromContext || i18n.options && i18n.options.defaultNS;
|
|
2650
|
-
namespaces = typeof namespaces === 'string' ? [namespaces] : namespaces || ['translation'];
|
|
2651
|
-
if (i18n.reportNamespaces.addUsedNamespaces) i18n.reportNamespaces.addUsedNamespaces(namespaces);
|
|
2652
|
-
const ready = (i18n.isInitialized || i18n.initializedStoreOnce) && namespaces.every(n => hasLoadedNamespace(n, i18n, i18nOptions));
|
|
2653
|
-
function getT() {
|
|
2654
|
-
return i18n.getFixedT(props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix);
|
|
2854
|
+
static createInstance() {
|
|
2855
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2856
|
+
let callback = arguments.length > 1 ? arguments[1] : undefined;
|
|
2857
|
+
return new I18n(options, callback);
|
|
2655
2858
|
}
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
isMounted.current = true;
|
|
2667
|
-
if (!ready && !useSuspense) {
|
|
2668
|
-
if (props.lng) {
|
|
2669
|
-
loadLanguages(i18n, props.lng, namespaces, () => {
|
|
2670
|
-
if (isMounted.current) setT(getT);
|
|
2671
|
-
});
|
|
2672
|
-
} else {
|
|
2673
|
-
loadNamespaces(i18n, namespaces, () => {
|
|
2674
|
-
if (isMounted.current) setT(getT);
|
|
2675
|
-
});
|
|
2859
|
+
cloneInstance() {
|
|
2860
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2861
|
+
let callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
|
|
2862
|
+
const forkResourceStore = options.forkResourceStore;
|
|
2863
|
+
if (forkResourceStore) delete options.forkResourceStore;
|
|
2864
|
+
const mergedOptions = {
|
|
2865
|
+
...this.options,
|
|
2866
|
+
...options,
|
|
2867
|
+
...{
|
|
2868
|
+
isClone: true
|
|
2676
2869
|
}
|
|
2677
|
-
}
|
|
2678
|
-
if (ready && previousJoinedNS && previousJoinedNS !== joinedNS && isMounted.current) {
|
|
2679
|
-
setT(getT);
|
|
2680
|
-
}
|
|
2681
|
-
function boundReset() {
|
|
2682
|
-
if (isMounted.current) setT(getT);
|
|
2683
|
-
}
|
|
2684
|
-
if (bindI18n && i18n) i18n.on(bindI18n, boundReset);
|
|
2685
|
-
if (bindI18nStore && i18n) i18n.store.on(bindI18nStore, boundReset);
|
|
2686
|
-
return () => {
|
|
2687
|
-
isMounted.current = false;
|
|
2688
|
-
if (bindI18n && i18n) bindI18n.split(' ').forEach(e => i18n.off(e, boundReset));
|
|
2689
|
-
if (bindI18nStore && i18n) bindI18nStore.split(' ').forEach(e => i18n.store.off(e, boundReset));
|
|
2690
2870
|
};
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
if (isMounted.current && !isInitial.current) {
|
|
2695
|
-
setT(getT);
|
|
2871
|
+
const clone = new I18n(mergedOptions);
|
|
2872
|
+
if (options.debug !== undefined || options.prefix !== undefined) {
|
|
2873
|
+
clone.logger = clone.logger.clone(options);
|
|
2696
2874
|
}
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2875
|
+
const membersToCopy = ['store', 'services', 'language'];
|
|
2876
|
+
membersToCopy.forEach(m => {
|
|
2877
|
+
clone[m] = this[m];
|
|
2878
|
+
});
|
|
2879
|
+
clone.services = {
|
|
2880
|
+
...this.services
|
|
2881
|
+
};
|
|
2882
|
+
clone.services.utils = {
|
|
2883
|
+
hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
|
|
2884
|
+
};
|
|
2885
|
+
if (forkResourceStore) {
|
|
2886
|
+
clone.store = new ResourceStore(this.store.data, mergedOptions);
|
|
2887
|
+
clone.services.resourceStore = clone.store;
|
|
2710
2888
|
}
|
|
2711
|
-
|
|
2889
|
+
clone.translator = new Translator(clone.services, mergedOptions);
|
|
2890
|
+
clone.translator.on('*', function (event) {
|
|
2891
|
+
for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
|
|
2892
|
+
args[_key4 - 1] = arguments[_key4];
|
|
2893
|
+
}
|
|
2894
|
+
clone.emit(event, ...args);
|
|
2895
|
+
});
|
|
2896
|
+
clone.init(mergedOptions, callback);
|
|
2897
|
+
clone.translator.options = mergedOptions;
|
|
2898
|
+
clone.translator.backendConnector.services.utils = {
|
|
2899
|
+
hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
|
|
2900
|
+
};
|
|
2901
|
+
return clone;
|
|
2902
|
+
}
|
|
2903
|
+
toJSON() {
|
|
2904
|
+
return {
|
|
2905
|
+
options: this.options,
|
|
2906
|
+
store: this.store,
|
|
2907
|
+
language: this.language,
|
|
2908
|
+
languages: this.languages,
|
|
2909
|
+
resolvedLanguage: this.resolvedLanguage
|
|
2910
|
+
};
|
|
2911
|
+
}
|
|
2712
2912
|
}
|
|
2913
|
+
const instance = I18n.createInstance();
|
|
2914
|
+
instance.createInstance = I18n.createInstance;
|
|
2915
|
+
|
|
2916
|
+
instance.createInstance;
|
|
2917
|
+
instance.dir;
|
|
2918
|
+
instance.init;
|
|
2919
|
+
instance.loadResources;
|
|
2920
|
+
instance.reloadResources;
|
|
2921
|
+
instance.use;
|
|
2922
|
+
instance.changeLanguage;
|
|
2923
|
+
instance.getFixedT;
|
|
2924
|
+
instance.t;
|
|
2925
|
+
instance.exists;
|
|
2926
|
+
instance.setDefaultNamespace;
|
|
2927
|
+
instance.hasLoadedNamespace;
|
|
2928
|
+
instance.loadNamespaces;
|
|
2929
|
+
instance.loadLanguages;
|
|
2713
2930
|
|
|
2714
2931
|
var locations$1 = {
|
|
2715
2932
|
label: "Location",
|
|
@@ -2851,70 +3068,30 @@ var fiCommon = {
|
|
|
2851
3068
|
errors: errors
|
|
2852
3069
|
};
|
|
2853
3070
|
|
|
2854
|
-
var
|
|
2855
|
-
|
|
2856
|
-
:
|
|
2857
|
-
var localeFromUrl = (urlParams === null || urlParams === void 0 ? void 0 : urlParams.get('locale')) || 'fi';
|
|
2858
|
-
instance.use(initReactI18next).init({
|
|
2859
|
-
resources: {
|
|
2860
|
-
en: { filterBar: enFilterBar, common: enCommon },
|
|
2861
|
-
fi: { filterBar: fiFilterBar, common: fiCommon },
|
|
2862
|
-
},
|
|
2863
|
-
lng: localeFromUrl,
|
|
2864
|
-
fallbackLng: 'fi',
|
|
2865
|
-
interpolation: {
|
|
2866
|
-
escapeValue: false,
|
|
2867
|
-
},
|
|
2868
|
-
});
|
|
2869
|
-
|
|
2870
|
-
var useUpdateTranslations = function (_a) {
|
|
2871
|
-
var language = _a.language;
|
|
2872
|
-
var _b = __read(useState(0), 2); _b[0]; var setRerenderKey = _b[1];
|
|
2873
|
-
useEffect(function () {
|
|
2874
|
-
instance.changeLanguage(language);
|
|
2875
|
-
setRerenderKey(function (prevKey) { return prevKey + 1; });
|
|
2876
|
-
}, [language]);
|
|
3071
|
+
var resources = {
|
|
3072
|
+
en: { filterBar: enFilterBar, common: enCommon },
|
|
3073
|
+
fi: { filterBar: fiFilterBar, common: fiCommon },
|
|
2877
3074
|
};
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
}
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
2893
|
-
};
|
|
2894
|
-
}, [filterSectionRef]);
|
|
2895
|
-
return { filterSectionRef: filterSectionRef };
|
|
3075
|
+
var readLocaleFromUrl = function () {
|
|
3076
|
+
if (typeof window === 'undefined')
|
|
3077
|
+
return null;
|
|
3078
|
+
return new URLSearchParams(window.location.search).get('locale');
|
|
3079
|
+
};
|
|
3080
|
+
var createI18nInstance = function (language) {
|
|
3081
|
+
var instance$1 = instance.createInstance();
|
|
3082
|
+
instance$1.use(initReactI18next).init({
|
|
3083
|
+
resources: resources,
|
|
3084
|
+
lng: language || readLocaleFromUrl() || 'fi',
|
|
3085
|
+
fallbackLng: 'fi',
|
|
3086
|
+
interpolation: { escapeValue: false },
|
|
3087
|
+
});
|
|
3088
|
+
return instance$1;
|
|
2896
3089
|
};
|
|
2897
3090
|
|
|
2898
|
-
var
|
|
2899
|
-
var
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
return;
|
|
2903
|
-
var attemptFocus = function (attempts) {
|
|
2904
|
-
if (attempts === void 0) { attempts = 0; }
|
|
2905
|
-
if (attempts > 20 || !ref.current)
|
|
2906
|
-
return;
|
|
2907
|
-
var focusable = ref.current.querySelector('button:not([disabled]), [tabindex]:not([tabindex="-1"])');
|
|
2908
|
-
if (focusable) {
|
|
2909
|
-
focusable.focus();
|
|
2910
|
-
}
|
|
2911
|
-
else {
|
|
2912
|
-
requestAnimationFrame(function () { return attemptFocus(attempts + 1); });
|
|
2913
|
-
}
|
|
2914
|
-
};
|
|
2915
|
-
requestAnimationFrame(function () { return attemptFocus(); });
|
|
2916
|
-
}, [autoFocus]);
|
|
2917
|
-
return ref;
|
|
3091
|
+
var I18nProvider = function (_a) {
|
|
3092
|
+
var language = _a.language, children = _a.children;
|
|
3093
|
+
var i18n = useMemo(function () { return createI18nInstance(language); }, []);
|
|
3094
|
+
return React__default.createElement(I18nextProvider, { i18n: i18n }, children);
|
|
2918
3095
|
};
|
|
2919
3096
|
|
|
2920
3097
|
var css_248z$j = ".will-filter-bar-select-button {\n width: 100%;\n height: auto;\n background-color: transparent;\n border: none;\n padding: 0 20px;\n border-radius: 20px;\n cursor: pointer;\n font-size: 14px;\n text-align: initial;\n user-select: none;\n}\n\n.will-filter-bar-select-button.disabled {\n cursor: not-allowed;\n}\n\n.will-filter-bar-select-button .select-button-wrapper {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 10px;\n}\n\n.will-filter-bar-select-button .select-button-wrapper > div {\n display: grid;\n}\n\n.will-filter-bar-select-button .select-button-label {\n color: var(--will-black);\n font-weight: 600;\n}\n\n.will-filter-bar-select-button .select-button-description {\n color: var(--will-black);\n font-weight: 400;\n opacity: 0.5;\n white-space: nowrap;\n min-height: 19px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.will-filter-bar-select-button .select-button-description span {\n font: inherit;\n}\n\n.will-filter-bar-select-button .select-button-label.active,\n.will-filter-bar-select-button .select-button-description.active {\n font-weight: 700;\n font-size: 15px;\n opacity: 1;\n}\n\n@media (max-width: 960px) {\n .will-filter-bar-select-button {\n padding: 15px 0;\n }\n\n .will-filter-bar-select-button:first-child {\n padding: 0 0 15px 0;\n }\n\n .will-filter-bar-select-button .select-button-wrapper {\n justify-content: center;\n text-align: center;\n }\n\n .will-filter-bar-select-button .select-button-description {\n white-space: wrap;\n }\n\n .will-filter-bar-select-button .select-button-divider {\n display: none;\n }\n}\n";
|
|
@@ -12257,12 +12434,12 @@ styleInject(css_248z$2);
|
|
|
12257
12434
|
var css_248z$1 = ".will-root {\n z-index: 999;\n width: fit-content;\n min-width: 796px;\n max-height: 100vh;\n position: relative;\n}\n\n.will-root.is-full-width {\n width: 100%;\n}\n\n.will-filter-bar {\n box-sizing: border-box;\n position: relative;\n}\n\n@media (max-width: 960px) {\n .will-root {\n width: 100%;\n min-width: auto;\n }\n}\n\n/* Common */\n\n.will-filter-bar-controls.dark,\n.will-filter-bar-panels.dark {\n box-shadow: var(--will-box-shadow-dark);\n}\n\n.will-filter-bar-controls.light,\n.will-filter-bar-panels.light {\n box-shadow: var(--will-box-shadow-light);\n}\n";
|
|
12258
12435
|
styleInject(css_248z$1);
|
|
12259
12436
|
|
|
12260
|
-
var FilterBar = function (
|
|
12437
|
+
var FilterBar = function (props) { return (React__default.createElement(I18nProvider, { language: props.language },
|
|
12438
|
+
React__default.createElement(FilterBarInner, __assign$2({}, props)))); };
|
|
12439
|
+
var FilterBarInner = function (_a) {
|
|
12261
12440
|
var language = _a.language, ageCategories = _a.ageCategories, _b = _a.redirectUrl, redirectUrl = _b === void 0 ? REDIRECT_URL_FALLBACK : _b, palette = _a.palette, onSubmit = _a.onSubmit, fullWidth = _a.fullWidth, disableCalendarDates = _a.disableCalendarDates, mode = _a.mode, tabs = _a.tabs, outerLoading = _a.outerLoading, locations = _a.locations;
|
|
12262
12441
|
var themePalette = useTheme({ palette: palette });
|
|
12263
|
-
// Translations
|
|
12264
12442
|
useUpdateTranslations({ language: language });
|
|
12265
|
-
// Display component after fully loaded
|
|
12266
12443
|
useAwaitRender();
|
|
12267
12444
|
return (React__default.createElement(FilterBarProvider, { language: language, ageCategories: ageCategories, redirectUrl: redirectUrl, palette: palette, onSubmit: onSubmit, fullWidth: fullWidth, disableCalendarDates: disableCalendarDates, mode: mode, tabs: tabs, outerLoading: outerLoading, locations: locations },
|
|
12268
12445
|
React__default.createElement("div", { className: "will-root ".concat(fullWidth ? 'is-full-width' : ''), style: themePalette },
|
|
@@ -12429,7 +12606,11 @@ var renderCalendarErrorMessage = function (_a) {
|
|
|
12429
12606
|
var css_248z = ".will-root .will-calendar-wrapper {\n box-shadow: var(--will-box-shadow-dark);\n border-radius: 20px;\n background-color: var(--will-white);\n position: absolute;\n top: 0;\n left: 0;\n \n}\n\n.will-root .will-calendar-wrapper .will-calendar-header,\n.will-root .will-calendar-wrapper .will-calendar-main,\n.will-root .will-calendar-wrapper .will-calendar-footer {\n padding: 20px;\n}\n\n/* Header */\n\n.will-root .will-calendar-wrapper .will-calendar-header {\n display: flex;\n justify-content: space-between;\n border-bottom: 1px solid var(--will-grey);\n align-items: center;\n}\n\n/* Footer */\n\n.will-root .will-calendar-wrapper .will-calendar-footer {\n border-top: 1px solid var(--will-grey);\n}\n\n/* Footer actions */\n\n.will-root .will-calendar-wrapper .will-calendar-footer-actions-wrapper {\n display: flex;\n justify-content: space-between;\n}\n\n.will-root .will-calendar-wrapper .will-calendar-footer-dates > div {\n margin-bottom: 5px;\n}\n\n.will-root .will-calendar-wrapper .will-calendar-footer-dates-separator {\n margin: 0 15px;\n}\n\n.will-root .will-calendar-wrapper .will-calendar-footer-dates .will-calendar-footer-booked {\n display: flex;\n min-height: 20.5px;\n margin-top: 10px;\n}\n\n.will-root .will-calendar-wrapper .will-calendar-footer-error {\n display: flex;\n max-width: 80%;\n}\n\n.will-root .will-calendar-wrapper .will-calendar-footer-error span {\n display: inline-block;\n margin-left: 10px;\n}\n\n@media (max-width: 960px) {\n .will-root .will-calendar-wrapper {\n width: -webkit-fill-available;\n margin: 0 -6%;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-header,\n .will-root .will-calendar-wrapper .will-calendar-main,\n .will-root .will-calendar-wrapper .will-calendar-footer {\n padding: 20px 10px;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-footer-actions-wrapper {\n flex-direction: column;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-footer-dates {\n text-align: center;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-footer-dates .will-calendar-footer-booked {\n justify-content: center;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-footer-actions {\n flex-direction: column;\n width: 100%;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-footer-actions button{\n width: 100%;\n margin-top: 10px;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-footer-error {\n max-width: 100%;\n }\n\n .will-root .will-calendar-wrapper .will-calendar-footer-error span {\n text-align: center;\n margin-left: 5px;\n }\n }\n\n.will-root .will-calendar-wrapper .will-calendar-header .will-filter-bar-close-button {\n position: initial;\n}";
|
|
12430
12607
|
styleInject(css_248z);
|
|
12431
12608
|
|
|
12432
|
-
function FilterCalendar(
|
|
12609
|
+
function FilterCalendar(props) {
|
|
12610
|
+
return (React__default.createElement(I18nProvider, { language: props.language },
|
|
12611
|
+
React__default.createElement(FilterCalendarInner, __assign$2({}, props))));
|
|
12612
|
+
}
|
|
12613
|
+
function FilterCalendarInner(_a) {
|
|
12433
12614
|
var calendarOffset = _a.calendarOffset, language = _a.language, palette = _a.palette, onSubmit = _a.onSubmit, outerDisableCalendarDates = _a.disableCalendarDates, toggleCalendar = _a.toggleCalendar, loadingData = _a.loadingData, setToggleCalendar = _a.setToggleCalendar, requestDates = _a.requestDates, showFeedback = _a.showFeedback, noActiveSelection = _a.noActiveSelection, outerRangeContext = _a.rangeContext;
|
|
12434
12615
|
var themePalette = useTheme({ palette: palette });
|
|
12435
12616
|
// Translations
|