This repository has been archived on 2022-07-28. You can view files and clone it, but cannot push or open issues or pull requests.
md-cms/edit/js/main.js

516 lines
22 KiB
JavaScript
Raw Normal View History

/**
* Removes a given element
*
* @param {DOMElement} id ID of the element to tear down.
*
* @return {void}
*/
async function removeElement(elem) {
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
elem.parentElement.removeChild(elem);
}
/**
* Function toggleHash toggles a specified location.hash value.
*
* @param {string} identifier ID to toggle.
*
* @return {void}
*/
function toggleHash(identifier) {
if (window.location.hash == "#" + identifier) window.location.hash = "";
else window.location.hash = "#" + identifier;
}
document.addEventListener("DOMContentLoaded", function() {
let translations = {
"en" : {
"uploadFile" : "Upload file",
"submit" : "Submit",
"filename" : "File Name",
"filetype" : "File Type",
"filesize" : "File Size",
"filemtime" : "Last modified",
"preview" : "Preview",
"generate" : "Generate",
"embedCodeGenerator" : "Generator for embed code",
"helpEmbedCode" : "Here you can create embed code.",
"singleObjectTile" : "Single object (tile)",
"singleObjectDetails" : "Single object (details)",
"singleCollectionTile" : "Single collection (tile)",
"singleCollectionDetails" : "Single collection (details)",
"singleInstitutionTile" : "Single institution (tile)",
"singleInstitutionDetails" : "Single institution (details)",
"singleExhibitionTile" : "Single exhibition (tile)",
"singleExhibitionDetails" : "Single exhibition (details)",
"singleEventTile" : "Single event (tile)",
"singleEventDetails" : "Single event (details)",
"exhibitionCalendar" : "Exhibition calendar",
"eventCalendar" : "Event calendar",
},
"de" : {
"uploadFile" : "Eine Datei heraufladen",
"submit" : "Abschicken",
"filename" : "Dateiname",
"filetype" : "Dateityp",
"filesize" : "Größe",
"filemtime" : "Zuletzt bearbeitet",
"preview" : "Vorschau",
"generate" : "Generieren",
"embedCodeGenerator" : "Generator für Einbettungen",
"helpEmbedCode" : "Hier können sie den embed-code generieren.",
"singleObjectTile" : "Einzelobjekt (Kachel)",
"singleObjectDetails" : "Einzelobjekt (Details)",
"singleCollectionTile" : "Einzelsammlung (Kachel)",
"singleCollectionDetails" : "Einzelsammlung (Details)",
"singleInstitutionTile" : "Einzelinstitution (Kachel)",
"singleInstitutionDetails" : "Einzelinstitution (Details)",
"singleExhibitionTile" : "Einzelne Ausstellung (Kachel)",
"singleExhibitionDetails" : "Einzelne Ausstellung (Details)",
"singleEventTile" : "Einzelne Veranstaltung (Kachel)",
"singleEventDetails" : "Einzelne Veranstaltung (Details)",
"exhibitionCalendar" : "Ausstellungskalender",
"eventCalendar" : "Veranstaltungen (Kalender)",
}
};
var debugging = false;
/**
* Function queryPage queries a web page and runs the specified function over the output.
*
* @param string url URL to query.
* @param function func Callback function to run on the request after loading.
* @param boolean debug Enable / disable debug mode.
*
* @return boolean
*/
function queryPage (url, func, debug = false) {
let request = new XMLHttpRequest();
request.open('GET', url);
request.setRequestHeader("Cache-Control", "no-cache");
request.responseType = 'htm';
request.send();
request.onload = function() {
func(request, debug);
};
}
/**
* Returns a requested translation from an array in the currently used language.
*
* @param mixed[] list Translation variable.
* @param string specifier Specifies which translation to get.
*
* @return string
*/
function getTranslation(list, specifier) {
let preferedLang = document.getElementsByTagName("html")[0].getAttribute("lang");
if (list[preferedLang] !== undefined && list[preferedLang][specifier] !== null) return list[preferedLang][specifier];
return list["en"][specifier];
}
/**
* Function to get all GET variables passed by user
* Based on gion_13's answer at https://stackoverflow.com/questions/12049620/how-to-get-get-variables-value-in-javascript
*
* @return string[]
*/
function getGETvars () {
var output = {};
if(document.location.toString().indexOf('?') !== -1) {
var query = document.location
.toString()
// get the query string
.replace(/^.*?\?/, '')
// and remove any existing hash string (thanks, @vrijdenker)
.replace(/#.*$/, '')
.split('&');
for(var i = 0, l = query.length; i < l; i++) {
var aux = decodeURIComponent(query[i]).split('=');
output[aux[0]] = aux[1];
}
}
return (output);
}
/**
* Allow toggling of navigation.
*/
(function() {
let navigationMode = window.localStorage.getItem("navigationMode");
if (navigationMode === undefined || navigationMode === null) {
window.localStorage.setItem("navigationMode", "1");
navigationMode = "1";
}
if (navigationMode === "0") {
document.getElementById("mainNav").classList.toggle("invisible");
}
document.getElementById("toggleNavigation").addEventListener("click", function(e) {
if (navigationMode === "0") {
window.localStorage.setItem("navigationMode", "1");
navigationMode = "1";
}
else {
window.localStorage.setItem("navigationMode", "0");
navigationMode = "0";
}
document.getElementById("mainNav").classList.toggle("invisible");
});
})();
/**
* Open the URL given in the href attribute of the element with the given ID.
*
* @param {string} identifier ID of the element with whose href to replace location.href
*
* @return {void}
*/
function replaceWindowById(identifier) {
var link = document.getElementById(identifier);
if (link != null) {
window.location.href = link.href;
}
}
(async function() {
let trigger = document.getElementById("uploadFile");
if (trigger === undefined || trigger === null) return;
trigger.addEventListener("click", function(e) {
let overlay = document.createElement("div");
overlay.classList.add("overlay");
let uploadForm = document.createElement("form");
uploadForm.enctype = "multipart/form-data";
uploadForm.action = "files.php";
uploadForm.method = "POST";
let uploadLabel = document.createElement("label");
uploadLabel.textContent = getTranslation(translations, "uploadFile");
uploadLabel.for = "fileUploadInput";
let uploadSize = document.createElement("input");
uploadSize.type = "hidden";
uploadSize.name = "MAX_FILE_SIZE";
uploadSize.value = "300000";
let uploadBackTo = document.createElement("input");
uploadBackTo.type = "hidden";
uploadBackTo.name = "backTo";
uploadBackTo.value = location.href;
let uploadTask = document.createElement("input");
uploadTask.type = "hidden";
uploadTask.name = "task";
uploadTask.value = "upload";
let uploadInput = document.createElement("input");
uploadInput.type = "file";
uploadInput.id = "fileUploadInput";
uploadInput.name = "file";
let uploadButton = document.createElement("button");
uploadButton.type = "submit";
uploadButton.textContent = getTranslation(translations, "submit");
uploadForm.appendChild(uploadLabel);
uploadForm.appendChild(uploadSize);
uploadForm.appendChild(uploadTask);
uploadForm.appendChild(uploadBackTo);
uploadForm.appendChild(uploadInput);
uploadForm.appendChild(uploadButton);
overlay.appendChild(uploadForm);
/**
* Function for generating file list.
*
* @param {DOMElement} parentElement Parent element to bind to.
* @param {function} callback Function to call on clicking on a file name.
* @param {string} sortOrder Sort order.
*
* @return {void}
*/
function generateFileList(parentElement, callback, sortOrder = '') {
let fileListDiv = document.createElement("div");
fileListDiv.id = "fileListDiv";
let fileList = document.createElement("table");
fileList.classList.add("fileList");
let target = './files.php';
if (sortOrder != '') {
target += '?sort=' + sortOrder;
}
function listFileListContents(target) {
queryPage(
encodeURI(target),
function (request) {
let allFiles = JSON.parse(request.response);
// Generate title line with sorting functionality
let fileTHLine = document.createElement("tr");
let fileLineTHName = document.createElement("th"); // Add TH for file name
fileLineTHName.textContent = getTranslation(translations, "filename"); // Display th contents
fileLineTHName.addEventListener('click', function(e) {
while (fileList.firstChild) { fileList.removeChild(fileList.firstChild); }
listFileListContents('./files.php');
});
fileTHLine.appendChild(fileLineTHName);
let fileLineTHType = document.createElement("th"); // Add TH for file type
fileLineTHType.textContent = getTranslation(translations, "filetype"); // Display th contents
fileLineTHType.addEventListener('click', function(e) {
while (fileList.firstChild) { fileList.removeChild(fileList.firstChild); }
listFileListContents('./files.php?sort=type');
});
fileTHLine.appendChild(fileLineTHType);
let fileLineTHMTime = document.createElement("th"); // Add TH for filemtime
fileLineTHMTime.textContent = getTranslation(translations, "filemtime"); // Display th contents
fileLineTHMTime.addEventListener('click', function(e) {
while (fileList.firstChild) { fileList.removeChild(fileList.firstChild); }
listFileListContents('./files.php?sort=mtime');
});
fileTHLine.appendChild(fileLineTHMTime);
let fileLineTHSize = document.createElement("th"); // Add TH for file size
fileLineTHSize.textContent = getTranslation(translations, "filesize"); // Display th contents
fileLineTHSize.addEventListener('click', function(e) {
while (fileList.firstChild) { fileList.removeChild(fileList.firstChild); }
listFileListContents('./files.php?sort=size');
});
fileTHLine.appendChild(fileLineTHSize);
fileList.appendChild(fileTHLine); // Append headline line to table
for (let i = 0, max = allFiles.length; i < max; i++) { // Loop over API outputs and print file lines.
let fileLine = document.createElement("tr");
let fileLineName = document.createElement("td"); // Add TD for displaying file name and main action
fileLineName.textContent = allFiles[i]["name"]; // Display file name
fileLineName.addEventListener('click', function(e) {
callback("../files/" + allFiles[i]["name"]);
});
fileLine.appendChild(fileLineName);
let fileLineType = document.createElement("td"); // Add TD for displaying file type
fileLineType.textContent = allFiles[i]["type"]; // Display file name
fileLine.appendChild(fileLineType);
let fileLineMTime = document.createElement("td"); // Add TD for displaying filemtime
fileLineMTime.textContent = allFiles[i]["mtime"]; // Display file name
fileLine.appendChild(fileLineMTime);
let fileLineSize = document.createElement("td"); // Add TD for displaying filemtime
fileLineSize.textContent = allFiles[i]["size"]; // Display file name
fileLine.appendChild(fileLineSize);
let fileLinePreview = document.createElement("td"); // Add TD for seing preview
fileLinePreview.textContent = getTranslation(translations, "preview"); // Display symbol
fileLinePreview.addEventListener('click', function(e) {
document.getElementById("filePreview").src = "../files/" + allFiles[i]["name"];
document.getElementById("filePreview").type = allFiles[i]['type'];
});
fileLine.appendChild(fileLinePreview);
let fileLineDelete = document.createElement("td"); // Add TD for deleting file
let fileLineDeleteLink = document.createElement("a"); // Add a.
fileLineDeleteLink.textContent = " \u2326 "; // Delete Symbole
fileLineDeleteLink.href = "files.php?task=delete&subject=" + encodeURI(allFiles[i]["name"]) + "&backTo=" + encodeURI(location.href);
fileLineDelete.appendChild(fileLineDeleteLink);
fileLine.appendChild(fileLineDelete);
fileList.appendChild(fileLine);
}
}
);
}
listFileListContents(target);
// Append to parent element
fileListDiv.appendChild(fileList);
parentElement.appendChild(fileListDiv);
// Offer preview
let preview = document.createElement("embed");
preview.id = "filePreview";
parentElement.appendChild(preview);
}
let fileOverlayRight = document.createElement("div");
generateFileList(fileOverlayRight, function(value) { location.href = value; });
overlay.appendChild(fileOverlayRight);
document.getElementsByTagName("body")[0].appendChild(overlay);
document.getElementsByTagName("body")[0].addEventListener('keydown', async function(e) {
if (e.keyCode != 27) return;
removeElement(overlay);
});
});
})();
/**
* Embed code generator.
*/
(function() {
function generateToolTip(toolTipID, toolTipText, toolTipTitle = "", triggerId = "") {
let trigger = document.createElement("span");
trigger.classList.add("newToolTipTag");
trigger.classList.add("helpToolTip");
trigger.setAttribute("data-for", toolTipID);
let toolTip = document.createElement("div");
toolTip.id = "tooltip_" + toolTipID;
toolTip.classList.add("newToolTip");
toolTip.setAttribute("data-title", toolTipTitle);
let toolTipCont = document.createElement("p");
toolTipCont.textContent = toolTipText;
toolTip.appendChild(toolTipCont);
trigger.appendChild(toolTip);
return trigger;
}
let generator = document.getElementById("embedGenerator");
if (generator === undefined || generator === null) return;
// Define generator types
let generatorTypes = [
["", "", false],
["singleObjectTile", getTranslation(translations, "singleObjectTile"), true],
["singleObjectDetails", getTranslation(translations, "singleObjectDetails"), true],
["singleCollectionTile", getTranslation(translations, "singleCollectionTile"), true],
["singleCollectionDetails", getTranslation(translations, "singleCollectionDetails"), true],
["singleInstitutionTile", getTranslation(translations, "singleInstitutionTile"), true],
["singleInstitutionDetails", getTranslation(translations, "singleInstitutionDetails"), true],
["singleExhibitionTile", getTranslation(translations, "singleExhibitionTile"), true],
["singleExhibitionDetails", getTranslation(translations, "singleExhibitionDetails"), true],
["singleEventTile", getTranslation(translations, "singleEventTile"), true],
["singleEventDetails", getTranslation(translations, "singleEventDetails"), true],
["exhibitionCalendar", getTranslation(translations, "exhibitionCalendar"), true],
["eventCalendar", getTranslation(translations, "eventCalendar"), true],
];
// Add help tooltip
let generatorLabelSpan = document.createElement("span");
generatorLabelSpan.classList.add("labelLine");
let generatorLabel = document.createElement("label");
generatorLabel.textContent = getTranslation(translations, "embedCodeGenerator");
generatorLabelSpan.appendChild(generatorLabel);
generatorLabelSpan.appendChild(generateToolTip("embedGeneratorToolTip", getTranslation(translations, "helpEmbedCode"), getTranslation(translations, "embedCodeGenerator")));
generator.appendChild(generatorLabelSpan);
let selectType = document.createElement("select");
for (let i = 0, max = generatorTypes.length; i < max; i++) {
let generatorOption = document.createElement("option");
generatorOption.value = generatorTypes[i][0];
generatorOption.textContent = generatorTypes[i][1];
generatorOption.setAttribute("data-useSpecifier", generatorTypes[i][2]);
selectType.appendChild(generatorOption);
}
generator.appendChild(selectType);
let generatorSpecifier = document.createElement("input");
generatorSpecifier.classList.add("invisible");
generator.appendChild(generatorSpecifier);
let buttonGenerate = document.createElement("a");
buttonGenerate.classList.add("buttonLike");
buttonGenerate.textContent = getTranslation(translations, "generate");
generator.appendChild(buttonGenerate);
let generatorField = document.createElement("fieldset");
let generatorFieldCont = document.createElement("div");
generatorField.appendChild(generatorFieldCont);
let generatorLegend = document.createElement("legend");
generatorField.appendChild(generatorLegend);
selectType.addEventListener('change', function(e) {
generatorSpecifier.value = "";
if (selectType.options[selectType.selectedIndex].getAttribute("data-useSpecifier") == "true") {
generatorSpecifier.classList.remove("invisible");
}
else generatorSpecifier.classList.add("invisible");
generatorLegend.textContent = selectType.options[selectType.selectedIndex].textContent;
generatorFieldCont.textContent = "";
});
function runGenerator() {
if (selectType.value == "") return;
generatorFieldCont.textContent = "[" + selectType.value + "]";
if (generatorSpecifier.value != "") {
generatorFieldCont.textContent += "{" + generatorSpecifier.value + "}";
}
}
generatorSpecifier.addEventListener('keydown', function(e) {
if (e.keyCode != 13) return;
e.stopPropagation(); e.preventDefault();
runGenerator();
});
buttonGenerate.addEventListener('click', function() { runGenerator(); });
generator.appendChild(generatorField);
if (debugging === true) {
console.log("Generated generator for pseudocode for embedding from museum-digital.");
}
})();
});