205 lines
6.6 KiB
JavaScript
205 lines
6.6 KiB
JavaScript
(function module() {
|
|
// 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 = [];
|
|
|
|
// The links that allow to change the language.
|
|
const languageChooserOptions = [];
|
|
|
|
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();
|
|
readUserPreferences();
|
|
updateMultiLanguageElements();
|
|
updateLanguageOptions();
|
|
}
|
|
|
|
/**
|
|
* 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(targetElement = contentArea) {
|
|
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);
|
|
updateLanguageOptions();
|
|
});
|
|
|
|
if (language === currentLanguage) {
|
|
languageLink.classList.add('active');
|
|
}
|
|
|
|
languageChooser.appendChild(languageLink);
|
|
languageChooserOptions.push(languageLink);
|
|
});
|
|
|
|
targetElement.prepend(languageChooser);
|
|
}
|
|
|
|
/**
|
|
* Marks the language option for the `currentLanguage` as `.active`.
|
|
*/
|
|
function updateLanguageOptions() {
|
|
languageChooserOptions.forEach(function (element) {
|
|
if (element.getAttribute('data-wiai-language') === currentLanguage) {
|
|
element.classList.add('active');
|
|
} else {
|
|
element.classList.remove('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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 preference—if any—from LocalStorage and update elements accordingly.
|
|
* In case there is no LocalStorage entry, but the user selected English as its default VC or browser
|
|
* language, the `currentLanguage` is set to English.
|
|
*/
|
|
function readUserPreferences() {
|
|
const localStorageEntry = localStorage.getItem(STORAGE_LANGUAGE_PREFERENCE_KEY);
|
|
const documentLanguage = document.querySelector('html').getAttribute('lang');
|
|
|
|
if (localStorageEntry != null) {
|
|
currentLanguage = localStorage.getItem(STORAGE_LANGUAGE_PREFERENCE_KEY);
|
|
} else if (documentLanguage === 'en' || documentLanguage === 'en_us'
|
|
|| navigator.language === 'en' || navigator.language.includes('en-')) {
|
|
currentLanguage = 'english';
|
|
}
|
|
document.body.classList.add(`wiai-language-${currentLanguage}`);
|
|
}
|
|
|
|
/**
|
|
* Store the user's language preference in LocalStorage.
|
|
*/
|
|
function writeUserPreferences() {
|
|
localStorage.setItem(STORAGE_LANGUAGE_PREFERENCE_KEY, currentLanguage);
|
|
}
|
|
})()
|