138 lines
4 KiB
JavaScript
138 lines
4 KiB
JavaScript
|
|
// TODO Optimalisatie: De huidige lijst meegeven en controleren tijdens het opstellen zodat er gestopt wordt vanaf er een titel gevonden is
|
|
|
|
// Initialiseer de webpagina
|
|
const taal = document.getElementById('taal');
|
|
const start = document.getElementById('start');
|
|
const einde = document.getElementById('einde');
|
|
const toevoegKnop = document.getElementById('toevoegKnop');
|
|
const visualisatie = document.getElementById('visualisatie');
|
|
const logo = document.getElementById('logo');
|
|
const waarschuwing = document.getElementById('waarschuwing');
|
|
|
|
let huidigeTaal;
|
|
let huidigeDoel;
|
|
|
|
let timer;
|
|
let rotatie;
|
|
|
|
refreshTree();
|
|
|
|
/**
|
|
* Zoek een pad met python backend en voeg deze toe in de lijst.
|
|
*/
|
|
function zoek() {
|
|
|
|
// Schakel de knop 'toevoegen' uit zolang het zoekproces bezig is, zodat er geen meerdere
|
|
// paden tegelijk toegevoegd kunnen worden.
|
|
toggleZoeken(false);
|
|
|
|
refreshTree();
|
|
|
|
const verzoek = { // Standaardwaarden gebruiken indien het veld leeg is.
|
|
taal: getOrDefault(taal),
|
|
start: getOrDefault(start),
|
|
einde: getOrDefault(einde)
|
|
};
|
|
|
|
fetch(`cgi-bin/init.py?data=${JSON.stringify(verzoek)}`)
|
|
.then(antwoord => antwoord.json())
|
|
.then(data => voegToe(data))
|
|
.catch(reason => alert('‼ ' + reason))
|
|
.finally(() => toggleZoeken()); // Herstel de knop. Ook als er ondertussen iets mis ging.
|
|
|
|
}
|
|
|
|
function voegToe(data) {
|
|
if (data.hasOwnProperty('error')) {
|
|
alert('↯ ' + data.error);
|
|
} else {
|
|
let pad = data.pad;
|
|
|
|
// Locatie van invoegen bepalen.
|
|
let moeder = visualisatie;
|
|
let kinderen = visualisatie.getElementsByTagName('li');
|
|
let kindernamen = Array.from(kinderen).map(item => item.getAttribute('item'));
|
|
let i = 0;
|
|
while (moeder === visualisatie && i < pad.length) {
|
|
if (kindernamen.indexOf(pad[i]) !== -1) {
|
|
moeder = kinderen[kindernamen.indexOf(pad[i])];
|
|
}
|
|
i += 1;
|
|
}
|
|
|
|
// Alleen nog die elementen toevoegen die nog niet op het pad staan.
|
|
pad = pad.slice(0, i - 1);
|
|
|
|
// Nieuw element creëren (zonder toe te voegen aan het DOM).
|
|
for (let item of pad.reverse()) {
|
|
moeder = maakIn(item, moeder);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Maakt een element aan binnen een ander element, en geeft het nieuwste (diepste) element terug.
|
|
*/
|
|
function maakIn(titel, moeder, id) {
|
|
let wrap = document.createElement('ul');
|
|
let nieuw = document.createElement('li');
|
|
nieuw.innerHTML = titel;
|
|
nieuw.setAttribute('item', titel);
|
|
wrap.appendChild(nieuw);
|
|
|
|
if (id !== undefined) {
|
|
wrap.id = id;
|
|
}
|
|
|
|
moeder.appendChild(wrap);
|
|
return nieuw;
|
|
}
|
|
|
|
/**
|
|
* Probeer of de huidige boom verwijderd moet worden en voeg de bestemming reeds toe aan de nieuwe boom.
|
|
*/
|
|
function refreshTree() {
|
|
if (huidigeDoel !== getOrDefault(einde) || huidigeTaal !== getOrDefault(taal)) {
|
|
huidigeTaal = getOrDefault(taal);
|
|
huidigeDoel = getOrDefault(einde);
|
|
|
|
visualisatie.innerHTML = '';
|
|
maakIn(huidigeDoel, visualisatie, 'wortel');
|
|
|
|
inputWaarschuwing();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toon of verberg een speciale waarschuwing die zegt of de huidige boom verwijderd zal worden
|
|
* bij een nieuwe toevoeging.
|
|
*/
|
|
function inputWaarschuwing() {
|
|
waarschuwing.hidden = (huidigeTaal === getOrDefault(taal) && huidigeDoel === getOrDefault(einde));
|
|
}
|
|
|
|
function getOrDefault(element) {
|
|
return element.value === '' ? element.getAttribute('placeholder') : element.value;
|
|
}
|
|
|
|
/**
|
|
* Toggle tussen de zoek-status en de wacht-op-input-status. Dit heeft invloed op zowel de indienkop als op het
|
|
* roterende logo. Standaardaanroep zal alles stoppen, om überveel animaties te vermijden bij fout gebruik.
|
|
*/
|
|
function toggleZoeken(stop = true) {
|
|
toevoegKnop.disabled = !stop;
|
|
|
|
rotatie = 0;
|
|
if (stop) {
|
|
clearInterval(timer);
|
|
logo.style.transform = 'rotate(0)';
|
|
} else {
|
|
timer = setInterval(draai, 24);
|
|
}
|
|
}
|
|
|
|
function draai() {
|
|
rotatie += 5;
|
|
logo.style.transform = `rotate(${rotatie % 360}deg`;
|
|
}
|