major: core 0.16

This commit is contained in:
Jean-Baptiste Pasquier
2021-03-16 15:27:30 +01:00
parent 668dfd04d7
commit 41a2910a4a
33 changed files with 418 additions and 115 deletions

View File

@ -6,17 +6,49 @@ class JsI18n {
constructor() {
this.locale = ""; //Current locale
this.locales = new Array(); //Available locales
this.defaultLocale = "fr";
}
/*
Method for automatically detecting the language, does not work in every browser.
*/
detectLanguage() {
const customLangs = document.querySelectorAll('hubl-lang');
if(customLangs) {
for(let lang of customLangs) {
let name = lang.getAttribute('lang'),
file = lang.getAttribute('file');
if(window.hubl.intl.locales[name.toString()] == undefined) {
return fetch(file).then((result) => {
if (result.ok) {
result.json().then(e => {
window.hubl.intl.addLocale(name, e);
});
}
window.hubl.intl.resumeDetection();
});
}
}
}
this.resumeDetection();
}
resumeDetection() {
const langComponent = document.querySelector('hubl-fallback-lang');
if(langComponent) {
if(langComponent.hasAttribute('lang')) {
this.defaultLocale = langComponent.getAttribute('lang');
if(langComponent.hasAttribute('force')) {
localStorage.setItem('language', this.defaultLocale);
}
}
}
if (localStorage.getItem('language') || (window.navigator.language !== null && window.navigator.language !== undefined)) {
this.fetchLocale(this.defaultLocale);
this.setLocale(localStorage.getItem('language') || window.navigator.language.slice(0, 2));
} else {
console.error('Language not found');
this.setLocale('fr');
this.setLocale(this.defaultLocale);
}
};
@ -105,38 +137,36 @@ class JsI18n {
this.locales[locale.toString()] = translations;
}
fetchLocale(locale) {
if(this.locales[locale.toString()] == undefined) {
return fetch(`/locales/${locale}.json`).then((result) => {
if (result.ok) {
result.json().then(e => {
this.addLocale(locale, e);
});
}
});
} else {
return (new Promise()).resolve();
}
}
/*
Sets the locale to use when translating.
*/
setLocale(locale) {
try {
fetch(`/locales/${locale}.json`).then((result) => {
if (result.ok) {
result.json().then(e => {
this.addLocale(locale, e);
this.processPage();
}).catch(() => {
if (locale != "fr") {
console.warn(`Locale not found: ${locale}, fallback to french`);
this.setLocale("fr");
} else {
console.error("Language not found");
}
});
} else {
if (locale != "fr") {
console.warn(`Locale not found: ${locale}, fallback to french`);
this.setLocale("fr");
} else {
console.error("Language not found");
}
this.fetchLocale(locale).then(() => {
if(this.locale) {
localStorage.setItem('language', this.locale);
}
this.processPage();
this.locale = locale;
});
this.locale = locale;
} catch {
if (locale != "fr") {
console.warn(`Locale not found: ${locale}, fallback to french`);
this.setLocale("fr");
if (locale != this.defaultLocale) {
console.warn(`Locale not found: ${locale}, fallback to ${this.defaultLocale}`);
this.setLocale(this.defaultLocale);
} else {
console.error("Language not found");
}
@ -148,12 +178,22 @@ class JsI18n {
*/
t(key) {
var translations = this.locales[this.locale];
if (translations != undefined) {
if (translations == undefined) {
translations = this.locales[this.defaultLocale];
}
if(translations != undefined) {
let translation = key.toString().split('.').reduce((o, i) => (o ? o[i] : undefined), translations);
if (typeof translation == "string") {
return translation;
} else {
return translations[key.toString()];
try {
let keySplitted = key.toString().split('.');
let first = keySplitted.shift();
translation = translations[first][keySplitted.join('.')];
return translation;
} catch {
return translations[key.toString()];
}
}
}
return undefined;
@ -176,21 +216,20 @@ class JsI18n {
}
//Global
jsI18n = new JsI18n;
window.hubl.intl = new JsI18n;
document.addEventListener("DOMContentLoaded", () => {
// Detect the lang & initialize, based on the browser or "language" item from localstorage
jsI18n.detectLanguage();
window.hubl.intl.detectLanguage();
let timer;
(new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.target.attributes["data-trans"] != null) {
// Render the target of the mutation instantly
jsI18n.processNode(mutation.target);
window.hubl.intl.processNode(mutation.target);
// Then wait one arbitrary second to re-render the whole document in case a widget re-rendered
clearTimeout(timer);
timer = setTimeout(() => jsI18n.processNode(document.querySelector('body')), 500);
timer = setTimeout(() => window.hubl.intl.processNode(document.querySelector('body')), 500);
}
});
}).observe(document.body, {
@ -198,9 +237,9 @@ document.addEventListener("DOMContentLoaded", () => {
childList: true
}));
document.addEventListener('widgetRendered', event => {
jsI18n.processNode(event.target);
window.hubl.intl.processNode(event.target);
// Then wait one arbitrary second to re-render the whole document in case a widget re-rendered
clearTimeout(timer);
timer = setTimeout(() => jsI18n.processNode(document.querySelector('body')), 500);
timer = setTimeout(() => window.hubl.intl.processNode(document.querySelector('body')), 500);
});
});

View File

@ -36,7 +36,7 @@ window.addEventListener("navigate", e => {
window.dispatchEvent(
new CustomEvent('requestNavigation', {
detail: {
route: window.hubl.getRoute("dashboard", true)
route: window.hubl.getRoute((window.hubl.defaultRoute || "dashboard"), true)
}
}),
);