Add bilinguality

This commit is contained in:
Linux User 2021-02-12 23:22:34 +01:00
commit e77f2438e4
2 changed files with 185 additions and 0 deletions

11
bilingual.css Normal file
View File

@ -0,0 +1,11 @@
.wiai-english {
display: none;
}
.wiai-language-english .wiai-english {
display: block;
}
.wiai-language-english .wiai-german {
display: none;
}

174
bilingual.js Normal file
View File

@ -0,0 +1,174 @@
// A list of all sections.
let sectionList;
// The main content area.
let contentArea;
// The language currently in use.
let currentLanguage = 'german';
// A hash of all elements explicitly marked as belonging to a language,
// e.g., by adding the class `wiai-german`.
const languageElements = {};
// All elements that contain multiple languages inline,
// separated by ' | '.
const multiLanguageElements = [];
const LANGUAGES = ['german', 'english'];
const LANGUAGE_NAMES = {'german': 'Deutsch', 'english': 'English'};
const LANGUAGE_PREFIXES = {'img[alt="German"]': 'german', 'img[alt="English"]': 'english'};
const URL = 'https://wiai.stuve-bamberg.de/vc-customization/';
const MULTI_LANGUAGE_CANDIDATE_QUERY = 'h1, h2, h3, h4, h5, span.instancename';
const STORAGE_LANGUAGE_PREFERENCE_KEY = 'wiai-language-preference';
window.addEventListener('load', init);
addStylesheetTag();
function init() {
initializeElements();
categorizeElementsByPrefix();
initializeMultiLanguageElements();
addLanguageChooser();
updateMultiLanguageElements();
readUserPreferences();
}
/**
* Add a link to the bilingual.css stylesheet.
*/
function addStylesheetTag() {
let tag = document.createElement('link');
tag.rel = 'stylesheet';
tag.href = URL + 'bilingual.css';
document.head.appendChild(tag);
}
/**
* Fill the `languageElements` hash with lists of objects that have explicit language classes (e.g., `wiai-german`),
* as well as the `sectionList` array of all main sections and the `contentArea` element.
*/
function initializeElements() {
LANGUAGES.forEach(function (language) {
languageElements[language] = Array.from(document.querySelectorAll(`.${getClassNameForLanguage(language)}`));
});
sectionList = Array.from(document.querySelectorAll('.topics .section.main'));
contentArea = document.querySelector('.course-content');
}
/**
* Add the language chooser element to the top of the `contentArea`.
*/
function addLanguageChooser() {
let languageChooser = document.createElement('div');
languageChooser.classList.add('wiai-language-chooser');
LANGUAGES.forEach(function (language) {
let languageLink = document.createElement('a');
languageLink.href = '#';
languageLink.classList.add('wiai-language-option');
languageLink.setAttribute('data-wiai-language', language);
languageLink.textContent = LANGUAGE_NAMES[language];
languageLink.addEventListener('click', function (event) {
event.preventDefault();
switchLanguage(currentLanguage, language);
let siblings = Array.from(link.parentElement.children);
siblings.forEach(function (element) { element.classList.remove('active'); })
link.classList.add('active');
});
languageChooser.appendChild(languageLink);
});
contentArea.prepend(languageChooser);
}
/**
* Update the language class on the document body (`wiai-language-XYZ`)
* and update all elements in `multiLanguageElements`.
* The `currentLanguage` is updated in the process.
*/
function switchLanguage(oldLanguage, newLanguage) {
document.body.classList.remove(`wiai-language-${oldLanguage}`);
document.body.classList.add(`wiai-language-${newLanguage}`);
currentLanguage = newLanguage;
writeUserPreferences();
updateMultiLanguageElements();
}
/**
* Update all `multiLanguageElements` to fit the new language.
**/
function updateMultiLanguageElements() {
multiLanguageElements.forEach(function (element) {
element.textContent = element.getAttribute(`data-wiai-title-${currentLanguage}`);
});
}
/**
* Add the correct language class to elements starting with one of the
* `LANGUAGE_PREFIXES`. The prefix is removed from the element itself.
*/
function categorizeElementsByPrefix() {
Object.keys(LANGUAGE_PREFIXES).forEach(function (languagePrefix) {
const language = LANGUAGE_PREFIXES[languagePrefix];
const prefixElements = document.querySelectorAll(languagePrefix);
prefixElements.forEach(function (prefixElement) {
const parent = prefixElement.parentElement;
parent.removeChild(prefixElement);
parent.classList.add(getClassNameForLanguage(language));
});
});
}
/**
* Find and process all elements containing multiple languages inline.
*/
function initializeMultiLanguageElements() {
const candidates = Array.from(contentArea.querySelectorAll(MULTI_LANGUAGE_CANDIDATE_QUERY));
candidates.forEach(initializeMultiLanguageElement);
}
/**
* Split the title of each `multiLanguageElement` and store the individual values
* in data attributes (`data-wiai-title-<language>`). The text content is then set
* to match the `currentLanguage`.
*/
function initializeMultiLanguageElement(element) {
const title = element.textContent;
if (title.includes(' | ')) {
const titleFragments = title.split(' | ');
for (let i = 0; i < titleFragments.length && i < LANGUAGES.length; i++) {
const language = LANGUAGES[i];
const localTitle = titleFragments[i];
element.setAttribute(`data-wiai-title-${language}`, localTitle);
multiLanguageElements.push(element);
}
element.textContent = element.getAttribute(`data-wiai-title-${currentLanguage}`);
}
}
function getClassNameForLanguage(language) {
return `wiai-${language}`;
}
/**
* Read the user's language preferenceif anyfrom LocalStorage and update elements accordingly.
*/
function readUserPreferences() {
if (localStorage.getItem(STORAGE_LANGUAGE_PREFERENCE_KEY) != null) {
currentLanguage = localStorage.getItem(STORAGE_LANGUAGE_PREFERENCE_KEY);
updateMultiLanguageElements();
}
}
/**
* Store the user's language preference in LocalStorage.
*/
function writeUserPreferences() {
localStorage.setItem(STORAGE_LANGUAGE_PREFERENCE_KEY, currentLanguage);
}