translations: Load translations from page_params.translation_data.

With this commit, we change how we deal with translation for strings.
Previously we used to fetch the translations data after loading which
created a lot of unpleasant race bugs.

So we changed this to use the `translation_data` sent in `page_params`
which is available at load time. The previous fetching can be useful if
we want to change the string to the changed language without reloading
the page but since we ask the user to reload the page after changing
the default language so fetching after loading isn't useful for us and
hence we can add resource only once.

Ultimately, we can remove the i18next plugins too.  We leave the logic
for clearing local storage, patched to fully clear it.

Fixes: #9087.
This commit is contained in:
Shubham Dhama 2018-05-29 16:04:59 +05:30 committed by Tim Abbott
parent 99c6a82b7f
commit cff40c557b
1 changed files with 10 additions and 62 deletions

View File

@ -1,79 +1,30 @@
// commonjs code goes here
import i18next from 'i18next';
import XHR from 'i18next-xhr-backend';
import LngDetector from 'i18next-browser-languagedetector';
import Cache from 'i18next-localstorage-cache';
import localstorage from './localstorage';
window.i18n = i18next;
// Add those keys in this list which are received from the backend
// and are translated by calling i18n.t function on variables. For example,
// i18n.t(receivedFromBackend);
var toBeTranslated = [ // eslint-disable-line no-unused-vars
// The Emoji type name for the "text" emojiset choice
i18n.t('Plain text'),
];
function loadPath(languages) {
var language = languages[0];
if (language.indexOf('-') >= 0) {
language = language.replace('-', '_'); // Change zh-Hans to zh_Hans.
}
return '/static/locale/' + language + '/translations.json';
}
var backendOptions = {
loadPath: loadPath,
};
var callbacks = [];
var initialized = false;
var detectionOptions = {
order: ['htmlTag'],
htmlTag: document.documentElement,
};
var cacheOptions = {
enabled: !page_params.development,
prefix: 'i18next:' + page_params.server_generation + ':',
expirationTime: 2*24*60*60*1000, // 2 days
};
i18next.use(XHR)
.use(LngDetector)
.use(Cache)
i18next
.init({
lng: 'lang',
resources: {
lang: {
translation: page_params.translation_data,
},
},
nsSeparator: false,
keySeparator: false,
interpolation: {
prefix: "__",
suffix: "__",
},
backend: backendOptions,
detection: detectionOptions,
cache: cacheOptions,
fallbackLng: 'en',
returnEmptyString: false, // Empty string is not a valid translation.
}, function () {
var i;
initialized = true;
for (i=0; i<callbacks.length; i += 1) {
callbacks[i]();
}
});
i18next.ensure_i18n = function (callback) {
if (initialized) {
callback();
} else {
callbacks.push(callback);
}
callback();
};
// garbage collect all old i18n translation maps in localStorage.
// garbage collect all old-style i18n translation maps in localStorage.
$(function () {
if (!localstorage.supported()) {
return;
@ -86,12 +37,9 @@ $(function () {
return /^i18next:\d{10}:\w+$/.test(key);
});
var current_generation_key = 'i18next:' + page_params.server_generation;
// remove cached translations of older versions.
translations.forEach(function (translation_key) {
if (translation_key.indexOf(current_generation_key) !== 0) {
localStorage.removeItem(translation_key);
}
localStorage.removeItem(translation_key);
});
return this;
});