Merge branch 'master' into release/hubl-618
This commit is contained in:
55
src/scripts/firefox-scroll.js
Normal file
55
src/scripts/firefox-scroll.js
Normal file
@ -0,0 +1,55 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const resizeChat = () => {
|
||||
let chatBox = Array.from(document.querySelectorAll("solid-xmpp-chat"))
|
||||
.map((el) => el.shadowRoot ? el.shadowRoot.getElementById("conversejs") : false)
|
||||
.filter((el) => el)
|
||||
.pop();
|
||||
if (chatBox) {
|
||||
let chatTextArea = chatBox.querySelector(".message-form-container");
|
||||
let ischatTextArea = setInterval(() => {
|
||||
chatTextArea = chatBox.querySelector(".message-form-container");
|
||||
if (chatTextArea) {
|
||||
clearInterval(ischatTextArea);
|
||||
if (
|
||||
chatBox.getBoundingClientRect().height -
|
||||
chatTextArea.getBoundingClientRect().height !=
|
||||
chatTextArea.offsetTop
|
||||
) {
|
||||
let viewportChat = Array.from(
|
||||
document.querySelectorAll("#viewport .chat-view")
|
||||
);
|
||||
viewportChat.forEach(
|
||||
(c) => (c.style.height = "calc(100vh - 106px - 57px - 4px)")
|
||||
);
|
||||
}
|
||||
}
|
||||
}, 15);
|
||||
}
|
||||
};
|
||||
resizeChat();
|
||||
|
||||
let isbody = setInterval(() => {
|
||||
if (document.body) {
|
||||
clearInterval(isbody);
|
||||
resizeChat();
|
||||
}
|
||||
}, 15);
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
setTimeout(() => {
|
||||
resizeChat();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
setTimeout(() => {
|
||||
resizeChat();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
document.addEventListener("navigate", () => {
|
||||
setTimeout(() => {
|
||||
resizeChat();
|
||||
}, 0);
|
||||
});
|
||||
});
|
198
src/scripts/intl.js
Normal file
198
src/scripts/intl.js
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
js intl, inspired by danabr/jsI18n
|
||||
*/
|
||||
class JsI18n {
|
||||
|
||||
constructor() {
|
||||
this.locale = ""; //Current locale
|
||||
this.locales = new Array(); //Available locales
|
||||
}
|
||||
|
||||
/*
|
||||
Method for automatically detecting the language, does not work in every browser.
|
||||
*/
|
||||
detectLanguage() {
|
||||
if (localStorage.getItem('language') || (window.navigator.language !== null && window.navigator.language !== undefined)) {
|
||||
this.setLocale(localStorage.getItem('language') || window.navigator.language.slice(0, 2));
|
||||
} else {
|
||||
console.error('Language not found');
|
||||
this.setLocale('fr');
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Translates tag contents and
|
||||
attributes depending on the
|
||||
value of key.
|
||||
*/
|
||||
translateTag(node, key) {
|
||||
if (key.indexOf("=") == -1) { //Simple key
|
||||
this.translateNodeContent(node, key);
|
||||
} else { //Attribute/key pairs
|
||||
var parts = key.split(";");
|
||||
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var pair = parts[i].split("=");
|
||||
var attr = pair[0].toLowerCase().trim();
|
||||
var k = pair[1].trim();
|
||||
|
||||
if (attr == "html") {
|
||||
this.translateNodeContent(node, k);
|
||||
} else {
|
||||
if(node.tagName == "SOLID-DELETE") {
|
||||
let button = node.querySelector('button');
|
||||
if(button != null) {
|
||||
this.translateNodeContent(button, k);
|
||||
}
|
||||
}
|
||||
this.translateNodeContent(node.attributes[attr], k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Replace the content of the given node
|
||||
if there is a translation for the given key.
|
||||
**/
|
||||
translateNodeContent(node, key) {
|
||||
var translation = this.t(key);
|
||||
if (node != null && translation != undefined) {
|
||||
if (node.nodeType == 1) { //Element
|
||||
try {
|
||||
node.innerHTML = translation;
|
||||
} catch (e) {
|
||||
node.text = translation;
|
||||
}
|
||||
} else if (node.nodeType == 2) { //Attribute
|
||||
node.value = translation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Helper for translating a node
|
||||
and all its child nodes.
|
||||
*/
|
||||
processNode(node) {
|
||||
if (node != undefined) {
|
||||
if (node.nodeType == 1) { //Element node
|
||||
|
||||
var key = node.attributes["data-trans"];
|
||||
if (key != null) {
|
||||
this.translateTag(node, key.nodeValue);
|
||||
}
|
||||
}
|
||||
|
||||
//Process child nodes
|
||||
var children = node.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
this.processNode(children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds a locale to the list,
|
||||
replacing the translations
|
||||
if the locale is already defined.
|
||||
*/
|
||||
addLocale(locale, translations) {
|
||||
this.locales[locale.toString()] = translations;
|
||||
}
|
||||
|
||||
/*
|
||||
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.locale = locale;
|
||||
} catch {
|
||||
if (locale != "fr") {
|
||||
console.warn(`Locale not found: ${locale}, fallback to french`);
|
||||
this.setLocale("fr");
|
||||
} else {
|
||||
console.error("Language not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fetches the translation associated with the given key.
|
||||
*/
|
||||
t(key) {
|
||||
var translations = this.locales[this.locale];
|
||||
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()];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/*
|
||||
Alias for JsI18n.t
|
||||
*/
|
||||
translate(key) {
|
||||
this.t(key);
|
||||
}
|
||||
|
||||
/**
|
||||
Replaces the contents of all tags
|
||||
that have the data-trans attribute set.
|
||||
**/
|
||||
processPage() {
|
||||
this.processNode(document.getElementsByTagName("html")[0]);
|
||||
}
|
||||
}
|
||||
|
||||
//Global
|
||||
jsI18n = new JsI18n;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
// Detect the lang & initialize, based on the browser or "language" item from localstorage
|
||||
jsI18n.detectLanguage();
|
||||
|
||||
/*
|
||||
recursivePopulate(DOMElement)
|
||||
Will listen for the populate event of any sib element
|
||||
Process the changed node every time it populate
|
||||
Recursively add a populate listener for children elements
|
||||
*/
|
||||
function recursivePopulate(element) {
|
||||
Array.from(element.querySelectorAll('*')).forEach((e) => {
|
||||
e.addEventListener("populate", (e) => {
|
||||
recursivePopulate(e.target);
|
||||
jsI18n.processNode(e.target);
|
||||
});
|
||||
});
|
||||
}
|
||||
// Process every children from document
|
||||
recursivePopulate(document);
|
||||
});
|
Reference in New Issue
Block a user