diff --git a/js/2.0.1-alt/buildForm.js b/js/2.0.1-alt/buildForm.js new file mode 100644 index 0000000..9a6f50b --- /dev/null +++ b/js/2.0.1-alt/buildForm.js @@ -0,0 +1,477 @@ +import { getFileName } from "./storage.js"; +import pell from "./pell.js" + +function transformTemplateObject(objects) { + let form = document.createElement("FORM"); + form.setAttribute("method", "post"); + form.setAttribute("action", "javascript:void(0)"); + form.setAttribute("id", "mainFormObj"); + form.classList.add("w3-row"); + + let sidebarList = document.createElement("ul"); + sidebarList.classList.add("w3-ul"); + + for (let i = 0; i < objects.length; i++) { + buildField(objects[i], form, sidebarList); + } + + //console.log(objects); + + //create sidebar submit button + let sidebarSubmitButton = document.createElement("li"); + sidebarSubmitButton.classList.add( + "w3-bar-item", + "w3-padding-large", + "w3-button" + ); + sidebarSubmitButton.style.borderTop = "2px solid #ddd"; + sidebarSubmitButton.id = "sb-submit"; + sidebarSubmitButton.innerHTML = "Save & Copy"; + sidebarList.appendChild(sidebarSubmitButton); + + //create sidebar set form button + let sidebarSetFormButton = document.createElement("li"); + sidebarSetFormButton.classList.add( + "w3-bar-item", + "w3-padding-large", + "w3-button" + ); + sidebarSetFormButton.style.borderTop = "2px solid #ddd"; + sidebarSetFormButton.id = "sb-setform"; + sidebarSetFormButton.innerHTML = "Set input as preset"; + sidebarList.appendChild(sidebarSetFormButton); + + + //add sidebar elemnts to sidebar + document.getElementById("sidebar").appendChild(sidebarList); + + //add form to mainForm Div + document.getElementById("mainForm").appendChild(form); + + //create username and append field to site + let fileName = getFileName(); + document.getElementById("submitContainer").appendChild(userFileNameDiv(fileName)); + + // create a Save button + let saveBtn = document.createElement("input"); + saveBtn.setAttribute("type", "submit"); + saveBtn.setAttribute("value", "Save"); + saveBtn.classList.add("w3-button"); + saveBtn.classList.add("w3-grey"); + saveBtn.style.margin = "20px"; + //append submit button to submitContainer + document.getElementById("submitContainer").appendChild(saveBtn); + + // create a Copy button + let copyBtn = document.createElement("input"); + copyBtn.setAttribute("type", "submit"); + copyBtn.setAttribute("value", "Copy"); + copyBtn.classList.add("w3-button"); + copyBtn.classList.add("w3-grey"); + copyBtn.style.margin = "20px 0px"; + copyBtn.id = "fromCopyBtn"; + //append submit button to submitContainer + document.getElementById("submitContainer").appendChild(copyBtn); + +} + + +function buildField(obj, form, sidebarList) { + //create template Input fields + + let divContainer = document.createElement("DIV"); + divContainer.classList.add("w3-half"); + divContainer.classList.add("w3-container"); + + let div = document.createElement("DIV"); + div.classList.add("w3-section"); + div.classList.add("w3-left-align"); + + div.setAttribute("style", "padding: 10px"); + + let label = document.createElement("LABEL"); + label.style.display = "inline-block"; + label.style.width = "100%"; + label.style.paddingBottom = "5px"; + label.style.borderBottom = "thin solid #9e9e9e"; + label.style.fontWeight = "800"; + + let connectedListsArray = []; + + let ltPlaceholder; + + //check for longtext:!li and convert it to standard longText + if (obj.type.indexOf("longText") !== -1) { + if (obj.type.indexOf(":") !== -1) { + ltPlaceholder = obj.type.split(":")[1]; + if (ltPlaceholder !== undefined) { + let textarea = document.createElement("textarea"); + textarea.setAttribute("name", obj.word.replace(/ /g, "_")); + textarea.setAttribute("cols", "100"); + textarea.setAttribute("rows", "15"); + textarea.classList.add("w3-input"); + textarea.id = obj.word.replace(/ /g, "_"); + divContainer.classList.remove("w3-half"); + divContainer.classList.add("w3-center"); + label.innerHTML = obj.word; + div.appendChild(label); + buildLongTextInput(div, textarea, label); + div.appendChild(textarea); + } + } + } + + + if (obj.type.indexOf("simpleInput") !== -1) { + if (obj.type.indexOf(":") !== -1) { + ltPlaceholder = obj.type.split(":")[1]; + if (ltPlaceholder !== undefined) { + let input = document.createElement("input"); + input.setAttribute("type", "text"); + input.setAttribute("name", obj.word.replace(/ /g, "_")); + input.setAttribute("id", obj.word.replace(/ /g, "_")); + input.classList.add("w3-input"); + input.id = obj.word.replace(/ /g, "_"); + label.innerHTML = obj.word; + div.appendChild(label); + div.appendChild(input); + } + } + } + + //check for markup:title and display it as none + if (obj.type.indexOf("markup") !== -1) { + if (obj.type.indexOf(":") !== -1) { + ltPlaceholder = obj.type.split(":")[1]; + if (ltPlaceholder !== undefined) { + divContainer.classList.add("hidden"); + let input = document.createElement("input"); + input.setAttribute("type", "text"); + input.setAttribute("name", obj.word.replace(/ /g, "_")); + input.id = obj.word.replace(/ /g, "_"); + input.value = obj.word; + divContainer.style.display = "none"; + label.innerHTML = obj.word; + div.appendChild(label); + div.appendChild(input); + } + } + } + + + switch (obj.type) { + case "genderSpecific": + let select = document.createElement("select"); + select.setAttribute("name", obj.word.replace(/ /g, "_")); + select.id = obj.word.replace(/ /g, "_"); + select.classList.add("w3-select"); + if (typeof obj.m !== "undefined") { + let optionM = document.createElement("option"); + optionM.value = obj.m; + optionM.text = obj.m; + select.appendChild(optionM); + } + if (typeof obj.w !== "undefined") { + let optionW = document.createElement("option"); + optionW.value = obj.w; + optionW.text = obj.w; + select.appendChild(optionW); + } + if (typeof obj.d !== "undefined") { + let optionD = document.createElement("option"); + optionD.value = obj.d; + optionD.text = obj.d; + select.appendChild(optionD); + } + label.innerHTML = obj.word; + div.appendChild(label); + div.appendChild(select); + break; + + case "list": + let select2 = document.createElement("select"); + select2.setAttribute("name", obj.word.replace(/ /g, "_")); + select2.classList.add("w3-select"); + select2.id = obj.word.replace(/ /g, "_"); + select2.setAttribute("id", obj.word.replace(/ /g, "_")); + + for (let listItem = 0; listItem < obj.listCount + 1; listItem++) { + //console.log(obj[listItem]); + if (typeof obj[listItem] !== "undefined") { + let optionL = document.createElement("option"); + optionL.value = obj[listItem]; + optionL.text = obj[listItem]; + select2.appendChild(optionL); + } + } + label.innerHTML = obj.word; + div.appendChild(label); + div.appendChild(select2); + break; + + case "conList": + let select3 = document.createElement("select"); + select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_")); + select3.classList.add("w3-select"); + select3.id = obj.word.replace(/ /g, "_"); + let optionDefault = document.createElement("option"); + optionDefault.value = "!none"; + optionDefault.text = "Choose one"; + select3.appendChild(optionDefault); + + + for (let listItem = 0; listItem < obj.listCount + 1; listItem++) { + //console.log(obj[listItem]); + if (typeof obj[listItem] !== "undefined") { + let optionL = document.createElement("option"); + let item = obj[listItem]; + optionL.value = item; + optionL.text = item; + select3.appendChild(optionL); + connectedListsArray.push({ + word: item, + type: obj["clType-"+item], + cl: obj.word + }); + } + } + label.innerHTML = obj.word; + + if (obj.listCount == 0) { + select3 = document.createElement("button"); + select3.setAttribute("value", "!none"); + select3.classList.add("w3-button", "w3-grey", "w3-left-align", "w3-padding-16"); + select3.id = obj.word.replace(/ /g, "_"); + select3.innerHTML = connectedListsArray[0].word; + select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_")); + select3.setAttribute("data-word", connectedListsArray[0].word); + label = document.createElement("LABEL"); + label.innerHTML = ''; + //div.classList.add("w3-center"); + div.classList.replace("w3-flat-silver", "w3-flat-clouds"); + div.appendChild(label); + div.appendChild(select3); + } else { + div.appendChild(label); + div.appendChild(document.createElement("br")); + div.appendChild(select3); + } + + + + break; + + case "simpleInput": + let input = document.createElement("input"); + input.setAttribute("type", "text"); + input.setAttribute("name", obj.word.replace(/ /g, "_")); + input.classList.add("w3-input"); + input.id = obj.word.replace(/ /g, "_"); + label.innerHTML = obj.word; + div.appendChild(label); + div.appendChild(input); + break; + case "longText": + let textarea = document.createElement("textarea"); + textarea.setAttribute("name", obj.word.replace(/ /g, "_")); + textarea.setAttribute("cols", "100"); + textarea.setAttribute("rows", "15"); + textarea.classList.add("w3-input"); + textarea.id = obj.word.replace(/ /g, "_"); + label.innerHTML = obj.word; + divContainer.classList.remove("w3-half"); + divContainer.classList.add("w3-center"); + div.appendChild(label); + buildLongTextInput(div, textarea, label); + div.appendChild(textarea); + break; + case "current_time": + let input2 = document.createElement("input"); + let today = new Date(); + let currentTime = + today.getHours() + ":" + ("0" + today.getMinutes()).slice(-2); + //console.log(currentTime); + input2.setAttribute("type", "text"); + input2.setAttribute("name", obj.word.replace(/ /g, "_")); + input2.setAttribute("value", currentTime); + input2.id = obj.word.replace(/ /g, "_"); + div.setAttribute("style", "display: none;"); + input2.classList.add("w3-input"); + label.innerHTML = obj.word; + div.appendChild(label); + div.appendChild(input2); + break; + case "current_date": + let input3 = document.createElement("input"); + var today2 = new Date(); + var dd = String(today2.getDate()).padStart(2, "0"); + var mm = String(today2.getMonth() + 1).padStart(2, "0"); //January is 0! + var yyyy = today2.getFullYear(); + currentDate = dd + "." + mm + "." + yyyy; + input3.setAttribute("type", "text"); + input3.setAttribute("name", obj.word.replace(/ /g, "_")); + input3.setAttribute("value", currentDate); + input3.id = obj.word.replace(/ /g, "_"); + div.setAttribute("style", "display: none;"); + input3.classList.add("w3-input"); + label.innerHTML = obj.word; + div.appendChild(label); + div.appendChild(input3); + break; + } + + //check if item is connected list item cl + if (obj.cl !== undefined) divContainer.classList.add("hidden"); + if (obj.cl !== undefined) { + div.lastChild.setAttribute("name", + (ltPlaceholder !== undefined) ? "cl-"+obj.word.replace(/ /g, "_") +":"+ltPlaceholder : "cl-"+obj.word.replace(/ /g, "_")); + divContainer.classList.add("w3-animate-opacity") + } + + //append field to wrapper and add to mainForm + divContainer.appendChild(div); + form.appendChild(divContainer); + + buildSidebarList(obj, sidebarList) + + //handle conList items + if (obj.type == "conList") { + //build connected list fields according to obj + for (let conObj of connectedListsArray) { + buildField(conObj, form, sidebarList); + } + + //set formEvent for selection detection to mainForm + if (obj.listCount == 0) { + document.getElementById("mainForm").addEventListener("click", (e) => { + if (e.target && e.target.matches("button#"+obj.word.replace(/ /g, "_"))) { + let button = document.getElementById(obj.word.replace(/ /g, "_")); + let con = button.dataset.word; + let conElement = document.getElementById(con); + if (conElement.parentElement.parentElement.classList.contains("hidden")) { + conElement.parentElement.parentElement.classList.remove("hidden"); + button.value = "!selected"; + } else { + conElement.parentElement.parentElement.classList.add("hidden"); + button.value = "!none"; + } + } + }); + } else { + document.getElementById("mainForm").addEventListener("change", (e) => { + if (e.target && e.target.matches("select#"+obj.word.replace(/ /g, "_"))) { + let select = document.getElementById(obj.word.replace(/ /g, "_")); + for (let opt of select.options) { + if (opt.value == "!none") continue; + if (opt.innerHTML != select.value) { + document.getElementById(opt.innerHTML.replace(/ /g, "_")).parentElement.parentElement.classList.add("hidden"); + } else { + document.getElementById(select.value.replace(/ /g, "_")).parentElement.parentElement.classList.remove("hidden"); + } + } + for (let hiddenItems of document.getElementsByClassName("cl")) { + if (hiddenItems.innerHTML != select.value) { + hiddenItems.classList.add("hidden"); + } else { + hiddenItems.classList.remove("hidden"); + } + } + } + }); + } + } +} + +function buildSidebarList(obj, sidebarList) { + //build sidebarlist item and append + let sidebarListItem = document.createElement("li"); + sidebarListItem.classList.add( + "w3-bar-item", + "w3-padding-large", + "w3-button", + "sb-item" + ); + if (obj.cl !== undefined) sidebarListItem.classList.add("hidden", "cl"); + sidebarListItem.style.borderBottom = "1px solid #ddd"; + sidebarListItem.id = "sb-item"; + sidebarListItem.setAttribute("data-item", obj.word.replace(/ /g, "_")); + sidebarListItem.innerHTML = obj.word; + sidebarListItem; + sidebarList.appendChild(sidebarListItem); +} + +function buildLongTextInput(source, textarea, label) { + + if (activeState.settings.enablePell == "false") return; + //hide default textarea + textarea.style.display = "none"; + label.style.display = "none"; + + + let title = document.createElement("b"); + title.innerText = label.innerText; + + const editor = pell.init({ + element: source, + defaultParagraphSeparator: "div", + actions: [ + "bold", + "italic", + "underline", + "strikethrough", + "paragraph", + "heading1", + "heading2", + { + name: 'ulist', + icon: 'L' + }, + "olist" + ], + onChange: function (html) { + //correct lastElement + activeState.lastElement = textarea.id; + textarea.value = html; + }, + }); + + let actionBar = editor.getElementsByClassName("pell-actionbar")[0]; + let content = editor.getElementsByClassName("pell-content")[0]; + + let actionBarElements = actionBar.getElementsByClassName("pell-button"); + let newActionBarElements = []; + for (let actionBarElement of actionBarElements ) { + actionBarElement.classList.add("w3-right"); + actionBarElement.setAttribute("tabindex","-1"); + newActionBarElements.push(actionBarElement); + } + //reverse actionbar back to org order + actionBar.innerHTML = ""; + for (let newActionBarElement of newActionBarElements.reverse()) { + actionBar.appendChild(newActionBarElement); + } + + actionBar.classList.add("w3-container"); + actionBar.style.paddingLeft = "0px"; + actionBar.appendChild(title); +} + +function userFileNameDiv(fileName) { + let divContainer = document.createElement("DIV"); + divContainer.classList.add("w3-third", "w3-container"); + divContainer.setAttribute("style", "padding: 0px"); + let div = document.createElement("DIV"); + div.classList.add("w3-section"); + div.setAttribute("style", "padding: 5px"); + let userFileNameInput = document.createElement("input"); + userFileNameInput.setAttribute("type", "text"); + userFileNameInput.setAttribute("name", "userFileName"); + userFileNameInput.setAttribute("placeholder", fileName); + userFileNameInput.classList.add("w3-input"); + userFileNameInput.id = "userFileName"; + div.appendChild(userFileNameInput); + divContainer.appendChild(div); + return divContainer; +} + +export default transformTemplateObject; diff --git a/js/2.0.1-alt/createTemplate.js b/js/2.0.1-alt/createTemplate.js new file mode 100644 index 0000000..a399bf0 --- /dev/null +++ b/js/2.0.1-alt/createTemplate.js @@ -0,0 +1,208 @@ +import {setNewTemplate, loadTemplate} from "./web.js"; +import { hideMenus, modalNotifier, resetNavBar } from "./evts.js"; +import { passwordHash, sanitize } from "./scripts.js"; + +function createTemplate(template = false) { + + //set current page value in activeState object + activeState.activePage = "createTemplate"; + + if (screen.width > 992) { + document.getElementById("siteTitle").innerHTML = "Manage templates"; + } else { + document.getElementById("siteTitle").innerHTML = "TG"; + document.getElementById("logo").innerHTML = "TG"; + } + + //sessionVerfication check + if (!passwordHash.verify()) { + modalNotifier("Error: Session is not authenticated...", 0, false); + } + + //reset navbar if files was used + resetNavBar(); + + //disable toggleTestBlocksMenu + document.getElementById("toggleTestBlocksMenu").style.display = "none"; + + + if (template) { + document.getElementById("templateInput").value = loadTemplate(template, false, "createTemplate"); + return; + } + + //reset page and event listeners + + hideMenus("force"); + + let mainFormDiv = document.getElementById("mainForm"); + let outputDiv = document.getElementById("output"); + let submitContainerDiv = document.getElementById("submitContainer"); + let sidebarDiv = document.getElementById("sidebar"); + + mainFormDiv.innerHTML = ""; + mainFormDiv.replaceWith(mainFormDiv.cloneNode(true)); + outputDiv.innerHTML = ""; + outputDiv.replaceWith(outputDiv.cloneNode(true)); + submitContainerDiv.innerHTML = ""; + submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true)); + sidebarDiv.innerHTML = ""; + sidebarDiv.replaceWith(sidebarDiv.cloneNode(true)); + + document.getElementById("mainForm").appendChild(createTemplateInput()); + document.getElementById("sidebar").appendChild(loadTemplateSidebar(activeState.templates)); + + //add events + if (!template) formEvts(); + } + + function createTemplateCallBack(fileName, data) { + + document.getElementById("templateInput").value = data; + document.getElementById("userFileName").setAttribute("placeholder", fileName); + } + + function loadTemplateSidebar(templates) { + let sidebarList = document.createElement("ul"); + sidebarList.classList.add("w3-ul"); + if (!templates.includes('_textBlocks')) { + templates.push('_textBlocks'); + } + + + for (let template of templates) { + let sidebarListItem = document.createElement("li"); + + sidebarListItem.classList.add( + "w3-bar-item", + "w3-padding-large", + "w3-button" + ); + sidebarListItem.style.borderBottom = "1px solid #ddd"; + sidebarListItem.id = "sb-item"; + sidebarListItem.setAttribute("data-template", template); + sidebarListItem.innerHTML = template.replace(/_/g, " "); + sidebarList.appendChild(sidebarListItem); + } + + return sidebarList; + + } + + function createTemplateInput() { + + let createTemplateDisplay = document.createElement("DIV"); + createTemplateDisplay.classList.add( + "w3-row-padding", + "w3-padding-24", + "w3-container", + "w3-flat-clouds" + ); + createTemplateDisplay.id = "createTemplateDisplayWrapper"; + + + //start building submitContainer with save and filename + + + document.getElementById("submitContainer").appendChild(userFileNameDiv()); + + let saveButton = document.createElement("input"); + saveButton.setAttribute("type", "submit"); + saveButton.setAttribute("value", "Save"); + saveButton.classList.add("w3-button"); + saveButton.classList.add("w3-grey"); + saveButton.style.margin = "20px"; + document.getElementById("submitContainer").appendChild(saveButton); + + + + let divContainer = document.createElement("DIV"); + divContainer.classList.add("w3-container", "w3-center"); + + let div = document.createElement("DIV"); + div.classList.add("w3-section"); + div.classList.add("w3-flat-silver"); + + div.setAttribute("style", "padding: 10px"); + + + + let textarea = document.createElement("textarea"); + textarea.setAttribute("name", "templateInput"); + textarea.setAttribute("id", "templateInput"); + textarea.setAttribute("cols", "100"); + textarea.setAttribute("rows", "30"); + textarea.classList.add("w3-input"); + + + div.appendChild(textarea); + divContainer.appendChild(div); + + + createTemplateDisplay.appendChild(divContainer); + return createTemplateDisplay; + + } + + + function formEvts() { + //add event listener to submitContainer + document.getElementById("submitContainer").addEventListener("click", (e) => { + if (e.target && e.target.tagName === "INPUT") { + switch (e.target.value) { + case "Save": + let fileName; + let userFileNameField = document.getElementById("userFileName"); + let userFileName = sanitize(userFileNameField.value); + let userFileNamePH = userFileNameField.getAttribute("placeholder"); + if (userFileName.length != 0) { + fileName = userFileName; + //clear old data as file switches to new filename + } else if (userFileNamePH.length != 0) { + fileName = userFileNamePH; + } + let data = document.getElementById("templateInput").value; + setNewTemplate(fileName, data); + modalNotifier(fileName+" saved!", activeState.settings.notifierPause); + e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis"); + e.target.style.pointerEvents = "none"; + const timeoutSave = setTimeout(() => { + e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey"); + e.target.style.pointerEvents = "auto"; + }, 250); + e.preventDefault; + break; + default: + e.preventDefault; + } + } + }); + document.getElementById("sidebar").addEventListener("click", (e) => { + if (e.target && e.target.matches("li.w3-bar-item")) { + let template = e.target.dataset.template; + createTemplate(template); + } + }); + } + + + + function userFileNameDiv() { + let divContainer = document.createElement("DIV"); + divContainer.classList.add("w3-third", "w3-container"); + divContainer.setAttribute("style", "padding: 0px"); + let div = document.createElement("DIV"); + div.classList.add("w3-section", "w3-margin-left"); + div.setAttribute("style", "padding: 5px"); + let userFileNameInput = document.createElement("input"); + userFileNameInput.setAttribute("type", "text"); + userFileNameInput.setAttribute("name", "userFileName"); + userFileNameInput.setAttribute("placeholder", "Enter a filename"); + userFileNameInput.classList.add("w3-input"); + userFileNameInput.id = "userFileName"; + div.appendChild(userFileNameInput); + divContainer.appendChild(div); + return divContainer; + } + +export {createTemplate, createTemplateCallBack}; \ No newline at end of file diff --git a/js/2.0.1-alt/evts.js b/js/2.0.1-alt/evts.js new file mode 100644 index 0000000..e452c7d --- /dev/null +++ b/js/2.0.1-alt/evts.js @@ -0,0 +1,314 @@ +import { passwordHash } from "./scripts.js"; +import { clearData, createBookShelf, importBookShelf } from "./storage.js"; +import { + loadTemplate, + storeFilesToServer, + checkForStoredDataOnServer, + delStoredDataOnServer, +} from "./web.js"; + +function showMenu() { + var x = document.getElementById("navMob"); + if (x.className.indexOf("w3-show") == -1) { + x.className += " w3-show"; + } else { + x.className = x.className.replace(" w3-show", ""); + } + + if (screen.width < 993) { + let sidebar = document.getElementById("sidebar"); + sidebar.style.display = "none"; + } +} +function showSidebar() { + let sidebar = document.getElementById("sidebar"); + if (getComputedStyle(sidebar).display === "none") { + sidebar.style.display = "block"; + sidebar.style.marginTop = "35px"; + } else { + sidebar.style.display = "none"; + } + + if (screen.width < 993) { + let navBar = document.getElementById("navMob"); + navBar.className = navBar.className.replace(" w3-show", ""); + } +} + +function showTextBlocks() { + var x = document.getElementById("navTb"); + if (x.className.indexOf("w3-show") == -1) { + x.className += " w3-show"; + } else { + x.className = x.className.replace(" w3-show", ""); + } + + if (screen.width < 993) { + let sidebar = document.getElementById("sidebar"); + sidebar.style.display = "none"; + } +} + +function insertTextBlocks(t) { + let insert = "!" + t.innerText.split(":")[0] + " "; + let id = activeState.lastElement; + let element = document.getElementById(id); + if (element === null) { + return; + } + element.value += " " + insert; + let tB = document.getElementById("navTb"); + tB.className.replace(" w3-show", ""); + + if (element.parentElement != undefined) { + if ( + element.parentElement.getElementsByClassName("pell-content")[0] != + undefined + ) { + element.parentElement.getElementsByClassName( + "pell-content" + )[0].innerHTML = element.value; + element = element.parentElement.getElementsByClassName("pell-content")[0]; + } + } + + element.focus(); +} + +function handleOnBlur(t) { + activeState.lastElement = t.id; + //createStorageObj(); +} + +function clickClearForm() { + //document.activeElement.blur(); + //document.getElementById("sidebar").focus(); + clearData("userInput"); + let lT = activeState.loadedTemplate; + loadTemplate(lT); +} + +function hideMenus(evt) { + if (evt === undefined) return; + if (evt != "force" && evt.target.parentElement != null) { + if (evt.target.parentElement.id == "navMob") return; + if (evt.target.parentElement.id == "navReg") return; + if (evt.target.parentElement.parentElement != null) { + if (evt.target.parentElement.parentElement.id == "navMob") return; + if (evt.target.parentElement.parentElement.id == "navReg") return; + } + } + let sidebar = document.getElementById("sidebar"); + sidebar.style.display = "none"; + let navBar = document.getElementById("navMob"); + navBar.className = navBar.className.replace(" w3-show", ""); + let tbBar = document.getElementById("navTb"); + tbBar.className = tbBar.className.replace(" w3-show", ""); +} + +function modalNotifier(msg, timeout = 3, closeable = true) { + let modalElement = document.getElementById("modalNotifier"); + let modalElementCloseBtn = document.getElementById("modalNotifierClose"); + let msgElement = document.getElementById("modalMsg"); + + modalElement.style.display = "block"; + + if (!closeable) modalElementCloseBtn.style.display = "none"; + + msgElement.innerHTML = msg; + if (timeout >= 1) { + const run = setTimeout( + () => (modalElement.style.display = "none"), + timeout * 1000 + ); + } +} + +function printVersion(msg = "") { + const scripts = document.getElementsByTagName("script"); + const versionSpan = document.getElementById("currentVersion").lastChild; + + for (var i = 0; i < scripts.length; i++) { + if (scripts[i].src) { + let source = scripts[i].src; + // js/version/main.js + let pathVersion = source.split("/"); + pathVersion = pathVersion[pathVersion.length - 2]; + //add it to document footer currentVersion + versionSpan.textContent = msg + " version: " + pathVersion; + } + } +} + +function clickImportFiles() { + if (activeState.settings.localOnly == "true") { + createBookShelfDownload(); + return; + } + checkForStoredDataOnServer(); + document.getElementById("modalMsg").addEventListener("click", (e) => { + if (e.target && e.target.tagName === "BUTTON") { + let modal = document.getElementById("modalNotifier"); + switch (e.target.innerHTML) { + case "Import": + modal.replaceWith(modal.cloneNode(true)); + document.getElementById("modalMsg").addEventListener("click", (e) => { + if (e.target && e.target.tagName === "BUTTON") { + let modal = document.getElementById("modalNotifier"); + + switch (e.target.innerHTML) { + case "Yes": + importBookShelf(); + modal.replaceWith(modal.cloneNode(true)); + modalNotifier( + "Imported!", + activeState.settings.notifierPause + ); + break; + case "Cancel": + modal.replaceWith(modal.cloneNode(true)); + document.getElementById("modalNotifier").style.display = + "none"; + break; + default: + e.preventDefault; + } + } + }); + modalNotifier( + "
created at: "+ts+" | template: "+template+"
"; + fileInfoDiv.style.display = "block"; + +} + +function loadFileDivCallBack() { + let tF = retrieveData("templateFiles"); + document.getElementById("sidebar").appendChild(loadFileSidebar(tF)); + + let lT = activeState.loadedTemplate; + let fN = activeState.fileName; + let storageName = fN + "_m21_" + lT; + + let fileDisplay = document.createElement("DIV"); + fileDisplay.classList.add( + "w3-row-padding", + "w3-padding-24", + "w3-container", + "w3-flat-clouds" + ); + fileDisplay.id = "fileDisplayWrapper"; + + //start building submitContainer with edit copy and delete + let editButton = document.createElement("input"); + editButton.setAttribute("type", "submit"); + editButton.setAttribute("value", "Edit"); + editButton.classList.add("w3-button"); + editButton.classList.add("w3-grey"); + document.getElementById("submitContainer").appendChild(editButton); + + document + .getElementById("submitContainer") + .appendChild(document.createTextNode(" ")); + + let copyButton = document.createElement("input"); + copyButton.setAttribute("type", "submit"); + copyButton.setAttribute("value", "Copy"); + copyButton.classList.add("w3-button"); + copyButton.classList.add("w3-grey"); + document.getElementById("submitContainer").appendChild(copyButton); + + document + .getElementById("submitContainer") + .appendChild(document.createTextNode(" ")); + + let deleteButton = document.createElement("input"); + deleteButton.setAttribute("type", "submit"); + deleteButton.setAttribute("value", "Delete"); + deleteButton.classList.add("w3-button"); + deleteButton.classList.add("w3-flat-pomegranate"); + document.getElementById("submitContainer").appendChild(deleteButton); + + if (screen.width > 992) { + document.getElementById("siteTitle").innerHTML = lT.replace(/_/g, " "); + } else { + document.getElementById("siteTitle").innerHTML = "TG"; + } + + let title = document.createElement("div"); + title.classList.add("w3-panel"); + let titleText = document.createElement("h2"); + titleText.innerText = fN.replace(/_/g, " "); + titleText.style.margin = "0px"; + title.appendChild(titleText); + fileDisplay.appendChild(title); + + let div = document.createElement("div"); + let parsedTemplate = parseFormOnSubmit(false, true); + div.appendChild(parsedTemplate); + + fileDisplay.appendChild(div); + + let ts = document.createElement("p"); + ts.innerHTML = "" + + //fileDisplay.appendChild(ts); + document.getElementById("mainForm").appendChild(fileDisplay); + + //fix min height of file display + try { + document.getElementById("fileDisplay").style.cssText = "min-height: 300px;"; + } catch (e) {} + //fix fontsize for display + try { + document.getElementById("fileDisplay").firstChild.style.fontSize = "1em"; + } catch (e) {} + //add events + formEvts(storageName); +} + +function clickLoadFileDiv(fileName, template, pos) { + if (fileName == "_overflow") return; + + if (fileName == "_clearAll") { + clickClearAllFiles(); + return; + } + + document.getElementById("mainForm").innerHTML = ""; + loadFileDiv(fileName, template, pos); +} + +function clearFileData(storData) { + let fileName = storData.split("_m21_")[0]; + + let tF = retrieveData("templateFiles"); + let newArray = []; + for (let obj of tF) { + if (obj.fileName != fileName) { + newArray.push(obj); + } + } + storeData("templateFiles", newArray); + + clearData(fileName); + clearData("userInput"); + + document.getElementById("mainForm").innerHTML = ""; + document.getElementById("output").innerHTML = ""; + document.getElementById("submitContainer").innerHTML = ""; + document.getElementById("sidebar").innerHTML = ""; + document.getElementById("mainForm").innerHTML = mainFormPlaceholder(); + document.getElementById("sidebar").appendChild(loadFileSidebar(newArray)); +} + +function loadFileSidebar(tF) { + let sidebarList = document.createElement("ul"); + sidebarList.classList.add("w3-ul"); + + let sidebarListItem = document.createElement("li"); + + sidebarListItem.classList.add( + "w3-padding-large", + ); + sidebarListItem.style.borderBottom = "1px solid #ddd"; + sidebarListItem.id = "sb-title"; + sidebarListItem.innerHTML = "Saved Files:" + sidebarList.appendChild(sidebarListItem); + + let c = 0; + let sidebarItemsAmount = 10; + for (let obj of tF.reverse()) { + sidebarListItem = document.createElement("li"); + sidebarListItem.classList.add( + "w3-bar-item", + "w3-padding-large", + "w3-button" + ); + sidebarListItem.style.borderBottom = "1px solid #ddd"; + sidebarListItem.id = "sb-" + obj.fileName.replace(/:/g, "_"); + + //handle to many files on screen and display hidden files amount + if (c > sidebarItemsAmount) { + sidebarListItem.setAttribute("data-template", "_overflow"); + sidebarListItem.setAttribute("data-file", "_overflow"); + sidebarListItem.style.backgroundColor = "#e3e7e8"; + sidebarListItem.classList.remove("w3-button"); + sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)"; + sidebarListItem.innerHTML = + tF.length - sidebarItemsAmount + " files not shown"; + sidebarList.appendChild(sidebarListItem); + break; + } + sidebarListItem.innerHTML = obj.fileName.replace(/_/g, " "); + sidebarListItem.setAttribute("data-file", obj.fileName); + sidebarListItem.setAttribute("data-template", obj.template); + sidebarListItem.setAttribute("data-tFPos", obj.pos); + sidebarList.appendChild(sidebarListItem); + c++; + } + + //clear all files button + sidebarListItem = document.createElement("li"); + sidebarListItem.classList.add("w3-bar-item", "w3-padding-large", "w3-button"); + sidebarListItem.setAttribute("data-template", "_clearAll"); + sidebarListItem.setAttribute("data-file", "_clearAll"); + sidebarListItem.classList.add("w3-hover-flat-pomegranate", "w3-bottom"); + sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)"; + sidebarListItem.style.width = "300px"; + sidebarListItem.innerHTML = "Clear all files"; + sidebarList.appendChild(sidebarListItem); + + return sidebarList; +} + +function mainFormPlaceholder(msg = "Select a file") { + return ( + "" +
+ msg +
+ "
Would you really like to delete all stored files?
\ + ", + 0 + ); +} +function clearAllFiles() { + let tF = retrieveData("templateFiles"); + if (tF == null || tF.length == 0) { + modalNotifier("there are no saved texts yet", activeState.settings.notifierPause); + return; + } + for (let storageName of tF) { + clearFileData(storageName.fileName); + } +} + +export { buildFile, loadFileDivCallBack }; diff --git a/js/2.0.1-alt/form.js b/js/2.0.1-alt/form.js new file mode 100644 index 0000000..d389085 --- /dev/null +++ b/js/2.0.1-alt/form.js @@ -0,0 +1,303 @@ + +import { storeData, createStorageObj } from "./storage.js"; +import parseInput from "./parseTemplate.js"; +import transformTemplateObject from "./buildForm.js"; +import { handleOnBlur, modalNotifier } from "./evts.js"; +import parseFormOnSubmit, { parseTextMarkups } from "./parseForm.js"; +import { setTemplatePreset } from "./web.js"; + +function buildForm(templateInput, loadOnly = false) { + var wordArray = []; + + //check for presets in "-form.txt" file; indicated by !JSON_placeholder + if (templateInput.indexOf("!JSON_placeholder:") !== -1) { + let jsonPlaceholder = templateInput.split("!JSON_placeholder:")[1]; + let placeholder; + try { + placeholder = JSON.parse(jsonPlaceholder); + } catch (e) { + placeholder = "" + } + templateInput = templateInput.split("!JSON_placeholder:")[0]; + storeData("templatePreset", placeholder); + } + //start building wordArray by splitting input by line win/unix and define eol char for recreating templateInput + let eol; + if (templateInput.indexOf("\r\n") !== -1) { + eol = false; + var wordArrayByLine = templateInput.split("\r\n"); + } else { + eol = true; + var wordArrayByLine = templateInput.split("\n"); + } + //finish building wordArray by Looping through lines and spliting it into one array of words + //also create temporary templateInput to exclude comments + let templateInputArr = []; + for (let wordArrayByLineLine of wordArrayByLine) { + //ignore "#" comment lines + if (wordArrayByLineLine.substring(0, 1) == "#") { + continue; + } + + //add words ob lines to wordArray + wordArray = wordArray.concat(wordArrayByLineLine.split(" ")); + //add line to temp templatearray + templateInputArr.push(wordArrayByLineLine); + } + + //create templateInput without comments + templateInput = templateInputArr.join(eol ? "\n" : "\r\n"); + + //parse text markups like !l !n in templateInput + templateInput = parseTextMarkups(templateInput); + + //set objects array for parseInput Function + var objects = []; + //loop through words, parse it individually and add it to objects array + + + for (let i = 0; i < wordArray.length; i++) { + parseInput(wordArray, objects, i); + //console.log(wordArray[i]); + } + + //set individual positionens of objects in string and add it to objects + setStringPos(objects, templateInput); + + //save objects array and template file string for web.js in session storage + activeState.templateObjects = objects; + activeState.fullString = templateInput; + + //sort objects array by words prio + objects = prioritizeArray(objects); + + //remove non display objects and safe it to session storage + let objectsPurified = purifyObjects(objects); + activeState.templateObjectsPurified = objectsPurified; + + //reset page and event listeners + let mainFormDiv = document.getElementById("mainForm"); + let outputDiv = document.getElementById("output"); + let submitContainerDiv = document.getElementById("submitContainer"); + let sidebarDiv = document.getElementById("sidebar"); + //sidebarDiv.replaceWith(sidebarDiv.cloneNode(true)); + + mainFormDiv.innerHTML = ""; + mainFormDiv.replaceWith(mainFormDiv.cloneNode(true)); + outputDiv.innerHTML = ""; + outputDiv.replaceWith(outputDiv.cloneNode(true)); + submitContainerDiv.innerHTML = ""; + submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true)); + sidebarDiv.innerHTML = ""; + + //finally build html code for Form and siddebar and add it to dom if needed + if (loadOnly) {return}; + + transformTemplateObject(objectsPurified); + //add events + formEvts(); +} + +function prioritizeArray(objects) { + let prioArray = []; + let objects_sorted = []; + + for (let valPreSorted of objects) { + prioArray.push(valPreSorted.prio); + } + prioArray.sort(function (a, b) { + return a - b; + }); + for (let valSorted of prioArray) { + for (let obj of objects) { + if (valSorted === obj.prio) { + objects_sorted.push(obj); + if (obj.prio !== 0) { + break; + } + } + } + } + return objects_sorted; +} + +function purifyObjects(objects) { + let objectsPurified = []; + let objectsPrePurified = []; + for (let objPrePurified of objects) { + if (!objectsPrePurified.includes(objPrePurified.word)) { + objectsPurified.push(objPrePurified); + } + objectsPrePurified.push(objPrePurified.word); + } + return objectsPurified; +} + +function setStringPos(objects, fullStringMaster) { + let stringCursor = 0; + let startPos = 0; + let endPos = 0; + let fullString = ""; + for (let obj of objects) { + fullString = fullStringMaster.substring(stringCursor); + if (fullString.indexOf("%" + obj.word) !== -1) { + startPos = 0; + endPos = 0; + startPos = fullString.indexOf("%" + obj.word) + stringCursor; + let objPrioLength = 1; + if (obj.prio > 9) { + objPrioLength = 2; + } + if (obj.prio == 0) { + objPrioLength = 0; + } + + switch (obj.type) { + case "simpleInput": + endPos = startPos + 2 + obj.word.length + objPrioLength; + break; + case "genderSpecific": + let gSC = 0; + if (typeof obj.m !== "undefined") { + gSC = gSC + obj.m.length + 3; + } + if (typeof obj.w !== "undefined") { + gSC = gSC + obj.w.length + 3; + } + if (typeof obj.d !== "undefined") { + gSC = gSC + obj.d.length + 3; + } + endPos = startPos + 2 + gSC + objPrioLength + obj.word.length + 1; + break; + case "list": + let gSC1 = 0; + for ( + let objListItem = 0; + objListItem < obj.listCount + 1; + objListItem++ + ) { + if (typeof obj[objListItem] !== "undefined") { + gSC1 = gSC1 + obj[objListItem].length + 3; + } + } + endPos = startPos + 2 + gSC1 + objPrioLength + obj.word.length + 1; + break; + case "conList": + let gSC2 = 0; + for ( + let objListItem = 0; + objListItem < obj.listCount + 1; + objListItem++ + ) { + if (typeof obj[objListItem] !== "undefined") { + gSC2 = gSC2 + obj[objListItem].length + obj["clType-"+obj[objListItem]].length + 4; + if (obj["clType-"+obj[objListItem]] == "cl-simpleInput") { + gSC2 = gSC2 - obj["clType-"+obj[objListItem]].length; + } + } + } + endPos = startPos + 2 + gSC2 + objPrioLength + obj.word.length + 1; + break; + default: + endPos = + startPos + + 2 + + obj.word.length + + 1 + + obj.type.length + + objPrioLength; + break; + } + obj.spos = startPos; + obj.epos = endPos; + stringCursor = endPos; + } + } +} + +function formEvts() { + //add event for main copy button + document.getElementById("submitContainer").addEventListener("click", (e) => { + if (e.target && e.target.tagName === "INPUT") { + switch (e.target.value) { + case "Copy": + createStorageObj(); + parseFormOnSubmit(); + e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot"); + e.target.style.pointerEvents = "none"; + e.target.value = "Copied"; + modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause); + const timeoutCopy = setTimeout(() => { + //e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey"); + //e.target.value = "Copy"; + e.target.style.pointerEvents = "auto"; + }, 5000); + break; + case "Save": + createStorageObj(); + e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis"); + e.target.style.pointerEvents = "none"; + modalNotifier(activeState.fileName + " saved", activeState.settings.notifierPause); + const timeoutSave = setTimeout(() => { + e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey"); + e.target.style.pointerEvents = "auto"; + }, 250); + break; + default: + e.preventDefault; + } + } + }); + + //add sidebar events + document.getElementById("sidebar").addEventListener("click", (e) => { + if (e.target) { + if (e.target.id == "sb-submit") { + parseFormOnSubmit(); + modalNotifier("File saved and copied to clipboard", activeState.settings.notifierPause); + } + if (e.target.id == "sb-setform") { + let dataArray = parseFormOnSubmit(true); + let lT = activeState.loadedTemplate; + setTemplatePreset(lT, JSON.stringify(dataArray)); + modalNotifier("Input saved as preset", activeState.settings.notifierPause); + } + if (e.target.id == "sb-item") { + setTimeout(() => { + focusOnField(e.target.dataset.item); + }, 100); + } + } + }); + + //add handle on blur event listener to each form object + let mainForm = document.getElementById("mainFormObj"); + for (let formElement of mainForm.children) { + let id = formElement.firstChild.lastChild.id; + document.getElementById(id).addEventListener("blur", (e) => { + e.preventDefault; + handleOnBlur(e.target); + }); + } +} + +function focusOnField(id) { + let targetElement = document.getElementById(id); + + //handle pell content focus + if (targetElement.parentElement != undefined) { + if (targetElement.parentElement.getElementsByClassName("pell-content")[0] != undefined) { + targetElement = targetElement.parentElement.getElementsByClassName("pell-content")[0]; + } + } + + if (targetElement == null) return; + document.activeElement.blur(); + targetElement.focus(); + setTimeout(function () { + let offset = targetElement.offsetTop - 100; + window.scrollTo(0, offset); + }, 100); +} + +export default buildForm; diff --git a/js/2.0.1-alt/identify.js b/js/2.0.1-alt/identify.js new file mode 100644 index 0000000..55d4687 --- /dev/null +++ b/js/2.0.1-alt/identify.js @@ -0,0 +1,247 @@ +const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, debug = false } = {}) => { + const devicePixelRatio = +parseInt(window.devicePixelRatio); + + const { + appName, + appCodeName, + appVersion, + cookieEnabled, + deviceMemory, + doNotTrack, + hardwareConcurrency, + language, + languages, + maxTouchPoints, + platform, + product, + productSub, + userAgent, + vendor, + vendorSub, + } = window.navigator; + + const { width, height, colorDepth, pixelDepth } = window.screen; + const timezoneOffset = new Date().getTimezoneOffset(); + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + const touchSupport = 'ontouchstart' in window; + + const canvas = getCanvasID(debug); + const webgl = enableWebgl ? getWebglID(debug) : undefined; // undefined will remove this from the stringify down here + const webglInfo = enableWebgl ? getWebglInfo(debug) : undefined; // undefined will remove this from the stringify down here + + const data = hardwareOnly + ? JSON.stringify({ + canvas, + colorDepth, + deviceMemory, + devicePixelRatio, + hardwareConcurrency, + height, + maxTouchPoints, + pixelDepth, + platform, + touchSupport, + webgl, + webglInfo, + width, + }) + : JSON.stringify({ + appCodeName, + appName, + appVersion, + canvas, + colorDepth, + cookieEnabled, + deviceMemory, + devicePixelRatio, + doNotTrack, + hardwareConcurrency, + height, + language, + languages, + maxTouchPoints, + pixelDepth, + platform, + product, + productSub, + timezone, + timezoneOffset, + touchSupport, + userAgent, + vendor, + vendorSub, + webgl, + webglInfo, + width, + }); + + const datastring = JSON.stringify(data, null, 4); + + if (debug) console.log('fingerprint data', datastring); + + const result = murmurhash3_32_gc(datastring); + return result; +}; + +export const getCanvasID = (debug) => { + try { + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?"; + ctx.textBaseline = 'top'; + ctx.font = "14px 'Arial'"; + ctx.textBaseline = 'alphabetic'; + ctx.fillStyle = '#f60'; + ctx.fillRect(125, 1, 62, 20); + ctx.fillStyle = '#069'; + ctx.fillText(text, 2, 15); + ctx.fillStyle = 'rgba(102, 204, 0, 0.7)'; + ctx.fillText(text, 4, 17); + + const result = canvas.toDataURL(); + + if (debug) { + document.body.appendChild(canvas); + } else { + ctx.clearRect(0, 0, canvas.width, canvas.height); + } + + return murmurhash3_32_gc(result); + } catch { + return null; + } +}; + +export const getWebglID = (debug) => { + try { + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('webgl'); + canvas.width = 256; + canvas.height = 128; + + const f = + 'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}'; + const g = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}'; + const h = ctx.createBuffer(); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, h); + + const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]); + + ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW), (h.itemSize = 3), (h.numItems = 3); + + const j = ctx.createProgram(); + const k = ctx.createShader(ctx.VERTEX_SHADER); + + ctx.shaderSource(k, f); + ctx.compileShader(k); + + const l = ctx.createShader(ctx.FRAGMENT_SHADER); + + ctx.shaderSource(l, g); + ctx.compileShader(l); + ctx.attachShader(j, k); + ctx.attachShader(j, l); + ctx.linkProgram(j); + ctx.useProgram(j); + + j.vertexPosAttrib = ctx.getAttribLocation(j, 'attrVertex'); + j.offsetUniform = ctx.getUniformLocation(j, 'uniformOffset'); + + ctx.enableVertexAttribArray(j.vertexPosArray); + ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0); + ctx.uniform2f(j.offsetUniform, 1, 1); + ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, h.numItems); + + const n = new Uint8Array(canvas.width * canvas.height * 4); + ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n); + + const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, ''); + + if (debug) { + document.body.appendChild(canvas); + } else { + ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT); + } + + return murmurhash3_32_gc(result); + } catch { + return null; + } +}; + +export const getWebglInfo = () => { + try { + const ctx = document.createElement('canvas').getContext('webgl'); + + const result = { + VERSION: ctx.getParameter(ctx.VERSION), + SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION), + VENDOR: ctx.getParameter(ctx.VENDOR), + SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(), + }; + + return result; + } catch { + return null; + } +}; + +export const murmurhash3_32_gc = (key) => { + const remainder = key.length & 3; // key.length % 4 + const bytes = key.length - remainder; + const c1 = 0xcc9e2d51; + const c2 = 0x1b873593; + + let h1, h1b, k1; + + for (let i = 0; i < bytes; i++) { + k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24); + ++i; + + k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff; + h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16); + } + + const i = bytes - 1; + + k1 = 0; + + switch (remainder) { + case 3: { + k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; + break; + } + case 2: { + k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + break; + } + case 1: { + k1 ^= key.charCodeAt(i) & 0xff; + break; + } + } + + k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; + h1 ^= k1; + + h1 ^= key.length; + + h1 ^= h1 >>> 16; + h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff; + h1 ^= h1 >>> 13; + h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff; + h1 ^= h1 >>> 16; + + return h1 >>> 0; +}; + +export default getBrowserFingerprint; diff --git a/js/2.0.1-alt/init.js b/js/2.0.1-alt/init.js new file mode 100644 index 0000000..139786e --- /dev/null +++ b/js/2.0.1-alt/init.js @@ -0,0 +1,183 @@ +import { + hideMenus, + showMenu, + showSidebar, + showTextBlocks, + clickImportFiles, + modalNotifier, + printVersion, + resetPage +} from "./evts.js"; +import { buildFile } from "./files.js"; +import setPassword, { + passwordHash, + inputRead +} from "./scripts.js"; +import parseFormOnSubmit from "./parseForm.js"; +import { createStorageObj, storeSettings } from "./storage.js"; +import { loadNavBar, initTextBlocks, loadNewTemplate } from "./web.js"; + +window.activeState = { + userId: "", + sessionToken: "", + activePage: "landing", + loadedTemplate: "", + fileName: "", + lastElement: "", + serverFilesTs: "", + settings: { + localOnly: "true", + lineBreak: 120, + font: "Arial", + fontSize: "10px", + notifierPause: 1, + persistentStorage: "false", + enablePell: "false", + }, + templates: [], + templateObjectsPurified: [], + templateObjects: [], + fullString: "", + templateFieldTypes: [ + "simpleInput", + "longText", + "hiddenField", + "current_time", + "current_date", + "markup", + ], + markups: ["title", "link", "italic", "green_highlighted", "highlighted"], + storage: [], + orgPage: { + main: {}, + sidebar: {} + } +}; + +function init() { + + //init passwordhash to retrieve cookie info and set passwordHash + passwordHash.initHash(); + + //check if user is logged in + if (passwordHash.verify()) { + //user logged in + document.getElementById("login").style.display = "none"; + } else { + document.getElementById("login").style.display = "block"; + } + + //load settings from storage and apply + let settings = storeSettings("getInit", true); + if (settings != null) { + for (let setting of Object.entries(settings)) { + activeState.settings[setting[0]] = setting[1]; + } + } + + //load NavigationBar with templates according to server + loadNavBar(); + + //init Textblocks field with entries according to server + initTextBlocks(); + + //add event listeners to document and window + eventListeners(); + + //print current version and storage mode to footer + let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent"; + printVersion("storage mode: "+msg+" |"); + + //adjust title for mobile use + if (screen.width < 993) { + document.getElementById("siteTitle").innerHTML = "TG"; + } + + //backup landing page + activeState.orgPage.sidebar = document.getElementById("sidebar"); + + activeState.orgPage.main = document.getElementById("mainForm"); +} + +function eventListeners() { + //add hideMenu to Body + document + .body + .addEventListener("click", (e) => hideMenus(e)); + + //add logo reset event + document + .getElementById("logo") + .addEventListener("click", resetPage); + + //add set Password to loginForm + document + .getElementById("submitPassword") + .addEventListener("click", setPassword); + //add toggle Navigation Menu + document + .getElementById("toggleNavigationMenu") + .addEventListener("click", showMenu); + //add loadTemplateBtn event showMenu +/* document + .getElementById("loadTemplateBtn") + .addEventListener("click", showMenu); */ + //add toggle sideBar Menu + document + .getElementById("toggleSidebarMenu") + .addEventListener("click", showSidebar); + //add toggle files Menu and sidebar button + document + .getElementById("toggleFilesMenuSB") + .addEventListener("click", buildFile); + document + .getElementById("toggleFilesMenu") + .addEventListener("click", buildFile); + + //add toggle textBLocks Menu + document + .getElementById("toggleTestBlocksMenu") + .addEventListener("click", showTextBlocks); + + //add saveFiles to server listener on launch page + document + .getElementById("importFilesSB") + .addEventListener("click", () => clickImportFiles()); + + //add key listener for ctrl s in form mode + inputRead.init(); + window.addEventListener("keydown", (e) => { + if (activeState.activePage == "template") { + inputRead.read(e); + if (e.ctrlKey && e.key == "s") { + createStorageObj(); + parseFormOnSubmit(); + modalNotifier("File copied to clipboard", activeState.settings.notifierPause); + let copyButton = document.getElementById("fromCopyBtn"); + copyButton.className = "w3-button w3-flat-carrot"; + copyButton.value = "Copied"; + e.preventDefault(); + } + } + }); + + //add url listener + window.addEventListener("hashchange", (e) => { + + let newURLArr = e.newURL.split("/"); + let template; + if (newURLArr != undefined) { + template = newURLArr[newURLArr.length -1]; + if (template != undefined) { + template = template.split("=")[1]; + if (template != undefined) { + if (activeState.templates.includes("")) { + loadNewTemplate(template); + } + } + } + } + }); +} + +init(); diff --git a/js/2.0.1-alt/parseForm.js b/js/2.0.1-alt/parseForm.js new file mode 100644 index 0000000..064eab5 --- /dev/null +++ b/js/2.0.1-alt/parseForm.js @@ -0,0 +1,445 @@ +import { sanitize } from "./scripts.js"; +import { storeData, clearData, retrieveData } from "./storage.js"; + +function parseFormOnSubmit(returnJSON = false, parseOnly = false) { + //event.preventDefault; + + let dataArray = []; + + if (parseOnly) { + let lT = activeState.loadedTemplate; + dataArray = retrieveData("userInputForce", lT); + + if (dataArray == null) { + let wrapper = document.createElement("div"); + wrapper.innerHTML = mainFormPlaceholder("Error: file empty"); + let div = wrapper.firstChild; + return div; + } + + if (dataArray.length <= 0) { + let wrapper = document.createElement("div"); + wrapper.innerHTML = mainFormPlaceholder("File empty"); + let div = wrapper.firstChild; + return div; + } + + } else { + let x = document.getElementById("mainFormObj"); + + if (x != null) { + for (let i = 0; i < x.length; i++) { + dataArray.push({ + value: x.elements[i].value, + name: x.elements[i].name, + }); + } + } + + //set filename to active state according to userFileName field from loadTemplate + let userFileNameField = document.getElementById("userFileName"); + let userFileName = sanitize(userFileNameField.value); + let userFileNamePH = userFileNameField.getAttribute("placeholder"); + if (userFileName.length != 0) { + activeState.fileName = userFileName; + } else if (userFileNamePH != null) { + activeState.fileName = userFileNamePH; + } + } + + + //get original objects from sessionstorage gen from loadTemplate + let objects = activeState.templateObjects; + + //get the complete unparsed template string from sessionstorage from loadTemplate + let fullString = activeState.fullString; + + //define output buffer + let b = ""; + + if (objects == null) { + return; + } + + //iterate through templateObjects and look for according formdata + for (let obj of objects) { + //compaire each obj with elements from mainFormObj + for (let data of dataArray) { + + //convert conList Master name to default name as set flag for appending connected list fields cl-name + let conListFlag = false; + //if obj is the connected list main selector + if (data.name.split("-")[0] == "clM") { + //if connected list main matches current object + if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) { + //set flag for next iteration of loop + conListFlag = true; + data.name = data.name.substring(4); + + //selection is not added to buffer + if (data.value == "!none") { + obj.result = ""; + continue; + } + if (data.value == "!selected") { + data.value = obj[0]; + obj.result = ""; + } + } + } + + //if field matches current object + if (obj.word.replace(/ /g, "_") == data.name) { + let value = parseDataForResult(obj, data.value); + if (value == "!none") value = ""; + obj.result = value; + + } + + //handle conlist elements for parsing each element + if (conListFlag && obj.type == "conList") { + let value = parseConListForResult(obj, data, dataArray); + if (value == "!none") value = ""; + obj.result = value; + continue; + } + } + } + + b = fullString.substring(0, objects[0].spos); + for (let i = 0; i < objects.length; i++) { + let j = i + 1; + if (objects[j] === undefined) { + b += + objects[i].result + + fullString.substring(objects[i].epos, fullString.length); + } else { + b += + objects[i].result + + fullString.substring(objects[i].epos, objects[j].spos); + } + } + + //sanitizing + let bHtml = b; + bHtml = bHtml.replace(/ /g, " "); + bHtml = bHtml.replace(/(?:\r\n|\r|\n)/g, "" + msg + "
"); + }, + }, + quote: { + icon: "“ ”", + title: "Quote", + result: function result() { + return exec(formatBlock, "
");
+ },
+ },
+ olist: {
+ icon: "#",
+ title: "Ordered List",
+ result: function result() {
+ return exec("insertOrderedList");
+ },
+ },
+ ulist: {
+ icon: "•",
+ title: "Unordered List",
+ result: function result() {
+ return exec("insertUnorderedList");
+ },
+ },
+ code: {
+ icon: "</>",
+ title: "Code",
+ result: function result() {
+ return exec(formatBlock, "");
+ },
+ },
+ line: {
+ icon: "―",
+ title: "Horizontal Line",
+ result: function result() {
+ return exec("insertHorizontalRule");
+ },
+ },
+ link: {
+ icon: "🔗",
+ title: "Link",
+ result: function result() {
+ var url = window.prompt("Enter the link URL");
+ if (url) exec("createLink", url);
+ },
+ },
+ image: {
+ icon: "📷",
+ title: "Image",
+ result: function result() {
+ var url = window.prompt("Enter the image URL");
+ if (url) exec("insertImage", url);
+ },
+ },
+ };
+
+ var defaultClasses = {
+ actionbar: "pell-actionbar",
+ button: "pell-button",
+ content: "pell-content",
+ selected: "pell-button-selected",
+ };
+
+ var init = function init(settings) {
+ var actions = settings.actions
+ ? settings.actions.map(function (action) {
+ if (typeof action === "string") return defaultActions[action];
+ else if (defaultActions[action.name])
+ return _extends({}, defaultActions[action.name], action);
+ return action;
+ })
+ : Object.keys(defaultActions).map(function (action) {
+ return defaultActions[action];
+ });
+
+ var classes = _extends({}, defaultClasses, settings.classes);
+
+ var defaultParagraphSeparator =
+ settings[defaultParagraphSeparatorString] || "div";
+
+ var actionbar = createElement("div");
+ actionbar.className = classes.actionbar;
+ appendChild(settings.element, actionbar);
+
+ var content = (settings.element.content = createElement("div"));
+ content.contentEditable = true;
+ content.className = classes.content;
+ content.oninput = function (_ref) {
+ var firstChild = _ref.target.firstChild;
+
+ if (firstChild && firstChild.nodeType === 3)
+ exec(formatBlock, "<" + defaultParagraphSeparator + ">");
+ else if (content.innerHTML === "
") content.innerHTML = "";
+ settings.onChange(content.innerHTML);
+ };
+ content.onkeydown = function (event) {
+ if (
+ event.key === "Enter" &&
+ queryCommandValue(formatBlock) === "blockquote"
+ ) {
+ setTimeout(function () {
+ return exec(formatBlock, "<" + defaultParagraphSeparator + ">");
+ }, 0);
+ }
+ };
+ appendChild(settings.element, content);
+
+ actions.forEach(function (action) {
+ var button = createElement("button");
+ button.className = classes.button;
+ button.innerHTML = action.icon;
+ button.title = action.title;
+ button.setAttribute("type", "button");
+ button.onclick = function () {
+ return action.result() && content.focus();
+ };
+
+ if (action.state) {
+ var handler = function handler() {
+ return button.classList[action.state() ? "add" : "remove"](
+ classes.selected
+ );
+ };
+ addEventListener(content, "keyup", handler);
+ addEventListener(content, "mouseup", handler);
+ addEventListener(button, "click", handler);
+ }
+
+ appendChild(actionbar, button);
+ });
+
+ if (settings.styleWithCSS) exec("styleWithCSS");
+ exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
+
+ return settings.element;
+ };
+
+ var pell = { exec: exec, init: init };
+
+ exports.exec = exec;
+ exports.init = init;
+ exports["default"] = pell;
+
+ Object.defineProperty(exports, "__esModule", { value: true });
+});
+
+export default pell;
diff --git a/js/2.0.1-alt/scripts.js b/js/2.0.1-alt/scripts.js
new file mode 100644
index 0000000..bb1b6d3
--- /dev/null
+++ b/js/2.0.1-alt/scripts.js
@@ -0,0 +1,239 @@
+import { clearStorage, createStorageObj, retrieveData } from "./storage.js";
+import sha256 from "./sha256.min.js";
+import XORCipher from "./xorc.js";
+import getBrowserFingerprint from "./identify.js"
+
+export const passwordHash = {
+ name: cyrb53("m21_"+getBrowserFingerprint( { hardwareOnly: true } )),
+ toString: function () {
+ let token = window.activeState.sessionToken;
+ if (token == null) return "";
+ if (token == "") return "";
+ return XORCipher.decode(this.name, token);
+ },
+ set: function (pw) {
+ if (pw == "") return;
+ activeState.sessionToken = XORCipher.encode(this.name, pw);
+ },
+ initHash: function () {
+ //check if cookie exists
+ if (getCookie(sha256(this.name)) != null) {
+ if (getCookie(sha256(this.name)) != "") {
+ this.set(XORCipher.decode(sha256(this.name), getCookie(sha256(this.name))));
+ }
+ }
+ let verifiedStatus = false;
+ let tF = retrieveData("templateFiles");
+ if (tF != null) {verifiedStatus = true}
+
+
+ if (verifiedStatus == true) {
+ //set user id
+ activeState.userId = getUsrId();
+ setCookie(sha256(this.name), XORCipher.encode(sha256(this.name), this), 10);
+ }
+ },
+ verify: function () {
+ if (passwordHash == "") return false;
+ let verifiedStatus = false;
+ let tF = retrieveData("templateFiles");
+ if (tF != null) verifiedStatus = true
+ return verifiedStatus;
+ }
+}
+
+function setPassword() {
+ let x = document.getElementById("loginForm");
+ let pw = sanitize(x.elements[0].value);
+
+ if (pw != "" || pw !== "undefined") {
+ passwordHash.set(sha256(pw));
+ let tF = retrieveData("templateFiles");
+ if (tF == null) {
+ wrongPwAlert();
+ passwordHash.set("");
+ x.elements[0].value = "";
+ return;
+ }
+ //user logged in
+
+ //make sure to bring back persistent stat after logout
+ activeState.settings.persistentStorage = "true";
+ tF = retrieveData("templateFiles");
+ if (tF == null || tF.length == 0) {
+ activeState.settings.persistentStorage = "false";
+ }
+
+ document.getElementById("login").style.display = "none";
+ setCookie(sha256(passwordHash.name), XORCipher.encode(sha256(passwordHash.name), passwordHash), 10)
+ }
+}
+
+function wrongPwAlert() {
+ let wrongPWAlert = document.getElementById("wrongPWAlert");
+ wrongPWAlert.style.display = "block";
+ wrongPWAlert.addEventListener("click", (e) => {
+ if (e.target && e.target.tagName === "A") {
+ clearStorage();
+ document.getElementById("wrongPWAlert").innerHTML =
+ "all files cleared - set new password
";
+ }
+ });
+}
+
+function cyrb53(str, seed = 21) {
+ let h1 = 0xdeadbeef ^ seed,
+ h2 = 0x41c6ce57 ^ seed;
+ for (let i = 0, ch; i < str.length; i++) {
+ ch = str.charCodeAt(i);
+ h1 = Math.imul(h1 ^ ch, 2654435761);
+ h2 = Math.imul(h2 ^ ch, 1597334677);
+ }
+
+ h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
+ h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
+
+ return 4294967296 * (2097151 & h2) + (h1 >>> 0);
+}
+
+function getUsrId() {
+ const fingerprint = getBrowserFingerprint( { hardwareOnly: true } );
+ return cyrb53(fingerprint + passwordHash);
+}
+
+function setCookie(cname, cvalue, exdays) {
+ const d = new Date();
+ d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
+ let expires = "expires="+d.toUTCString();
+ document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
+}
+
+function getCookie(cname) {
+ let name = cname + "=";
+ let ca = document.cookie.split(';');
+ for(let i = 0; i < ca.length; i++) {
+ let c = ca[i];
+ while (c.charAt(0) == ' ') {
+ c = c.substring(1);
+ }
+ if (c.indexOf(name) == 0) {
+ return c.substring(name.length, c.length);
+ }
+ }
+ return null;
+}
+
+export function logout() {
+ let id = sha256(passwordHash.name);
+ activeState.sessionToken = "";
+ setCookie(sha256(passwordHash.name), "", 10);
+ document.cookie = id + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
+ document.getElementById("passwordField").value = "";
+ document.getElementById("login").style.display = "block";
+}
+
+
+
+export function sanitize(string) {
+ const map = {
+ '&': '_',
+ '<': '_',
+ '>': '_',
+ '"': '_',
+ "'": '_',
+ '/': '_',
+ '`': '_',
+ '=': '_'
+ };
+ const reg = /[&<>"'/]/ig;
+ return string.replace(reg, (match)=>(map[match]));
+}
+
+export function isAlphaNumeric(str) {
+ var code, i, len;
+
+ for (i = 0, len = str.length; i < len; i++) {
+ code = str.charCodeAt(i);
+ if (!(code > 47 && code < 58) && // numeric (0-9)
+ !(code > 64 && code < 91) && // upper alpha (A-Z)
+ !(code > 96 && code < 123)) { // lower alpha (a-z)
+ return false;
+ }
+ }
+ return true;
+};
+
+export const inputRead = {
+ init: function () {
+ this.event = "";
+ this.inputString = "";
+ this.source = "";
+ this.inputContent = "";
+ this.lastRunTime = new Date();
+ this.target = document.getElementById("toggleFilesMenu");
+ this.lastExecId = "";
+ },
+ read: function (event) {
+ this.event = event;
+ this.source = event.srcElement.id;
+ if (event.target.className == "pell-content") {
+ this.source = event.target.parentElement.getElementsByTagName("textarea")[0].id;
+ }
+ let previousContent = this.inputContent;
+ let key = (event.key !=undefined) ? event.key : "";
+ let contentElement = document.getElementById(this.source);
+ this.inputContent = (contentElement != undefined) ? contentElement.value + key : "";
+
+ if (this.inputContent == "" || key == "") return;
+ if (key.length > 1) return;
+ if (event.ctrlKey) return;
+ if (this.inputContent == previousContent) return;
+
+ this.lastRunTime = new Date();
+ clearTimeout(this.lastExecId);
+
+ this.target.style.borderBottom = "3px solid #c0392b";
+ this.target.innerHTML = "";
+ let i = document.createElement("i");
+ i.classList.add("fa", "fa-save");
+ this.target.appendChild(i);
+ this.lastExecId = setTimeout(() => {
+ createStorageObj();
+ this.target.style.borderBottom = "none";
+ this.target.innerHTML = "";
+ let i = document.createElement("i");
+ i.classList.add("fa", "fa-file");
+ this.target.appendChild(i);
+ }, 1000);
+ },
+}
+
+export function getCurrentDate() {
+ let date = new Date();
+ let uts = Date.now();
+ let current_hour = date.getHours();
+ current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
+ let current_minute = date.getMinutes();
+ current_minute = current_minute <= 9 ? "0" + current_minute : current_minute;
+ let current_second = date.getSeconds();
+ current_second = current_second <= 9 ? "0" + current_second : current_second;
+ let current_month = date.getMonth() + 1;
+ current_month = current_month <= 9 ? "0" + current_month : current_month;
+ let current_day = date.getDate();
+ current_day = current_day <= 9 ? "0" + current_day : current_day;
+ let current_year = date.getFullYear();
+
+
+ let current_time = current_hour + ":" + current_minute;
+ let current_time_long = current_hour + ":" + current_minute + ":" + current_second;
+ let current_date = current_day + "." + current_month;
+ return {
+ current_time: current_time,
+ current_time_long: current_time_long,
+ current_date: current_date,
+ current_year: current_year,
+ uts: uts
+ };
+}
+
+export default setPassword;
diff --git a/js/2.0.1-alt/settings.js b/js/2.0.1-alt/settings.js
new file mode 100644
index 0000000..4a8535e
--- /dev/null
+++ b/js/2.0.1-alt/settings.js
@@ -0,0 +1,210 @@
+import { hideMenus, modalNotifier, printVersion, resetNavBar } from "./evts.js";
+import { passwordHash, sanitize } from "./scripts.js";
+import { retrieveData, storeData, storeSettings } from "./storage.js";
+
+const buildSettings = () => {
+ //set current page value in activeState object
+ activeState.activePage = "settings";
+
+ if (screen.width > 992) {
+ document.getElementById("siteTitle").innerHTML = "Settings";
+ } else {
+ document.getElementById("siteTitle").innerHTML = "TG";
+ document.getElementById("logo").innerHTML = "TG";
+ }
+
+ //sessionVerfication check
+ if (!passwordHash.verify()) {
+ modalNotifier("Error: Session is not authenticated...", 0, false);
+ }
+
+ //reset navbar if files was used
+ resetNavBar();
+
+ //disable toggleTestBlocksMenu
+ document.getElementById("toggleTestBlocksMenu").style.display = "none";
+
+ //reset page and event listeners
+
+ hideMenus("force");
+
+ let mainFormDiv = document.getElementById("mainForm");
+ let outputDiv = document.getElementById("output");
+ let submitContainerDiv = document.getElementById("submitContainer");
+ let sidebarDiv = document.getElementById("sidebar");
+
+ mainFormDiv.innerHTML = "";
+ mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
+ outputDiv.innerHTML = "";
+ outputDiv.replaceWith(outputDiv.cloneNode(true));
+ submitContainerDiv.innerHTML = "";
+ submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
+ sidebarDiv.innerHTML = "";
+ sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
+
+ addSidebar();
+
+ buildForm();
+
+ //add events
+ formEvts();
+};
+
+function formEvts() {
+ //add event listener to submitContainer
+ document.getElementById("submitContainer").addEventListener("click", (e) => {
+ if (e.target && e.target.tagName === "INPUT") {
+ switch (e.target.value) {
+ case "Save":
+ saveSettings();
+ modalNotifier(
+ "Settings saved!",
+ activeState.settings.notifierPause
+ );
+ e.target.className = e.target.className.replace(
+ " w3-grey",
+ " w3-flat-nephritis"
+ );
+ e.target.style.pointerEvents = "none";
+ const timeoutSave = setTimeout(() => {
+ e.target.className = e.target.className.replace(
+ " w3-flat-nephritis",
+ " w3-grey"
+ );
+ e.target.style.pointerEvents = "auto";
+ }, 250);
+ e.preventDefault;
+ break;
+ default:
+ e.preventDefault;
+ }
+ }
+ });
+}
+
+
+function buildForm() {
+ let form = document.createElement("FORM");
+ form.setAttribute("method", "post");
+ form.setAttribute("action", "javascript:void(0)");
+ form.setAttribute("id", "mainFormObj");
+ form.classList.add("w3-row");
+
+ let settings = storeSettings("get", true);
+ if (settings == "") settings = activeState.settings;
+
+ for (let setting of Object.entries(settings)) {
+ buildField(setting, form);
+ }
+
+ //add form to mainForm Div
+ document.getElementById("mainForm").appendChild(form);
+
+ // create a Save button
+ let saveBtn = document.createElement("input");
+ saveBtn.setAttribute("type", "submit");
+ saveBtn.setAttribute("value", "Save");
+ saveBtn.classList.add("w3-button");
+ saveBtn.classList.add("w3-grey");
+ saveBtn.style.margin = "20px";
+ //append submit button to submitContainer
+
+ document.getElementById("submitContainer").appendChild(saveBtn);
+}
+
+function buildField(obj, form) {
+
+ //create template Input fields
+ let divContainer = document.createElement("DIV");
+ divContainer.classList.add("w3-half");
+ divContainer.classList.add("w3-container");
+
+ let div = document.createElement("DIV");
+ div.classList.add("w3-section");
+ div.classList.add("w3-left-align");
+
+ div.setAttribute("style", "padding: 10px");
+
+ let label = document.createElement("LABEL");
+ label.style.display = "inline-block";
+ label.style.width = "100%";
+ label.style.paddingBottom = "5px";
+ label.style.borderBottom = "thin solid #9e9e9e";
+ label.style.fontWeight = "800";
+
+ let input = document.createElement("input");
+ input.setAttribute("type", "text");
+ input.setAttribute("name", obj[0]);
+ input.setAttribute("id", obj[0]);
+ input.classList.add("w3-input");
+ input.id = obj[0];
+ input.value = obj[1];
+ label.innerHTML = obj[0];
+ div.appendChild(label);
+ div.appendChild(input);
+ //append field to wrapper and add to mainForm
+ divContainer.appendChild(div);
+ form.appendChild(divContainer);
+}
+
+function addSidebar() {
+ let sidebarList = document.createElement("ul");
+ sidebarList.classList.add("w3-ul");
+
+ let sidebarListItem = document.createElement("li");
+
+ sidebarListItem.classList.add(
+ "w3-bar-item",
+ "w3-padding-large",
+ "w3-button"
+ );
+ sidebarListItem.style.borderBottom = "1px solid #ddd";
+ sidebarListItem.id = "sb-title";
+ sidebarListItem.innerHTML = "Edit Settings"
+ sidebarList.appendChild(sidebarListItem);
+
+ document.getElementById("sidebar").appendChild(sidebarList);
+
+}
+
+function saveSettings() {
+ let x = document.getElementById("mainFormObj");
+ let obj = {};
+ if (x == null) {
+ return;
+ }
+ for (let i = 0; i < x.length; i++) {
+ let name = x.elements[i].name;
+ let value = x.elements[i].value;
+ obj[name] = sanitize(value);
+ }
+ for (let setting of Object.entries(obj)) {
+ if (activeState.settings[setting[0]] != setting[1]) {
+ //change detected
+ if (setting[0] == "persistentStorage") {
+ //get tF from old storage
+ let tF = retrieveData("templateFiles");
+ //get previous settings
+ let settings = storeSettings("get", true);
+ //store the new settings in old storage
+ storeSettings(obj);
+ //apply the new setting
+ activeState.settings[setting[0]] = setting[1];
+
+ //store the new settings in the new storage
+ if (settings != "") storeSettings(obj);
+ //transfer tF
+ if (tF != null) storeData("templateFiles", tF);
+
+ let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent";
+ printVersion("storage mode: "+msg+" |");
+
+ }
+ }
+ activeState.settings[setting[0]] = setting[1];
+ }
+ storeSettings(obj);
+}
+
+
+export default buildSettings;
diff --git a/js/2.0.1-alt/sha256.min.js b/js/2.0.1-alt/sha256.min.js
new file mode 100644
index 0000000..4aa510b
--- /dev/null
+++ b/js/2.0.1-alt/sha256.min.js
@@ -0,0 +1,3 @@
+var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;ed;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
+
+export default sha256;
\ No newline at end of file
diff --git a/js/2.0.1-alt/storage.js b/js/2.0.1-alt/storage.js
new file mode 100644
index 0000000..fb9b533
--- /dev/null
+++ b/js/2.0.1-alt/storage.js
@@ -0,0 +1,291 @@
+import XORCipher from "./xorc.js";
+import sha256 from "./sha256.min.js";
+import { getCurrentDate, passwordHash, sanitize } from "./scripts.js";
+
+const store = {
+ getItem: function (key) {return getStor().getItem(sha256(key+activeState.userId))},
+ setItem: function (key, data) {getStor().setItem(sha256(key+activeState.userId), data)},
+ removeItem: function (key) {getStor().removeItem(sha256(key+activeState.userId))},
+ clear: function () {getStor().clear()},
+};
+
+const tempStore = {
+ setItem: function (key, data) {
+ globalThis.activeState.storage[key] = data;
+ },
+ getItem: function (key) {
+ return globalThis.activeState.storage[key];
+ },
+ removeItem: function (key) {
+ globalThis.activeState.storage[key] = "";
+ },
+ clear: function () {
+ globalThis.activeState.storage = [];
+ },
+};
+
+function getStor() {
+ if (window.activeState.settings.persistentStorage == "true") {
+ return window.localStorage;
+ } else {
+ return tempStore;
+ }
+}
+
+function createStorageObj() {
+ let x = document.getElementById("mainFormObj");
+ let dataArray = [];
+ if (x == null) {
+ return;
+ }
+ for (let i = 0; i < x.length; i++) {
+ dataArray.push({
+ value: x.elements[i].value,
+ name: x.elements[i].name,
+ });
+ }
+
+ //console.log(this, dataArray);
+
+ let userFileNameField = document.getElementById("userFileName");
+ let userFileName = sanitize(userFileNameField.value);
+ let userFileNamePH = userFileNameField.getAttribute("placeholder");
+ if (userFileName.length != 0) {
+ activeState.fileName = userFileName;
+ //clear old data as file switches to new filename
+ if (userFileNamePH.length != 0) {
+ clearData(userFileNamePH);
+ popFromTemplateFiles(userFileNamePH);
+ }
+ } else if (userFileNamePH.length != 0) {
+ activeState.fileName = userFileNamePH;
+ }
+
+ storeData("userInput", dataArray);
+}
+
+function storeData(name, data) {
+ if (passwordHash == "") return;
+ data = JSON.stringify(data);
+ //setCookie(name, btoa(data), 7);
+ if (name == "userInput") {
+ name = getFileName();
+ }
+ if (name == "userInputForce") {
+ name = "userInput";
+ }
+ let lT = activeState.loadedTemplate;
+ let key = sha256(name + "_m21_" + lT);
+ if (name == "templateFiles") {
+ key = sha256(name + "_m21_" + activeState.userId);
+ }
+ store.setItem(key, obfuscate(data));
+}
+
+function retrieveData(name, template = "none") {
+ if (passwordHash == "") return null;
+ if (name == "userInput") {
+ let tF = retrieveData("templateFiles");
+ if (tF == null) {
+ return [];
+ } else {
+ name = tF[tF.length - 1].fileName;
+ }
+ }
+ if (name == "userInputForce") {
+ name = "userInput";
+ }
+ let cdata;
+ let key;
+ if (template == "none") {
+ let lT = activeState.loadedTemplate;
+ key = sha256(name + "_m21_" + lT);
+ if (name == "templateFiles") {
+ key = sha256(name + "_m21_"+activeState.userId);
+ }
+ } else {
+ key = sha256(name + "_m21_" + template);
+ }
+ cdata = store.getItem(key);
+
+ if (cdata != null) {
+ cdata = obfuscate(cdata, false);
+ let data;
+ try {
+ data = JSON.parse(cdata);
+ } catch (e) {
+ data = null;
+ }
+ return data;
+ } else {
+ return [];
+ }
+}
+
+function clearData(name, template = "none") {
+ let lT;
+ let key;
+ if (template == "none") {
+ lT = activeState.loadedTemplate;
+ key = sha256(name + "_m21_" + lT);
+ if (name == "templateFiles") {
+ key = sha256(name + "_m21_"+activeState.userId);
+ }
+ } else {
+ lT = template;
+ key = sha256(name + "_m21_" + template);
+ }
+ store.removeItem(key);
+}
+
+function getFileName(ref = "none") {
+ let currentFileName = activeState.fileName;
+ let lT = activeState.loadedTemplate;
+ if (currentFileName == "none" || currentFileName == "") {
+ let date = getCurrentDate();
+ currentFileName = date.current_time + "_" + date.current_date + " " + lT;
+ //console.log(currentFileName);
+ }
+
+ let tF = retrieveData("templateFiles");
+ const metadata = {
+ ts_create: getCurrentDate(),
+ ts_save: "",
+ id: sha256(currentFileName),
+ };
+
+ if (tF.length != 0) {
+ for (let tFi of tF) {
+ if (tFi.fileName == currentFileName) {
+ tFi.metadata.ts_save = getCurrentDate();
+ return currentFileName;
+ }
+ }
+ tF.push({
+ fileName: currentFileName,
+ template: lT,
+ metadata: metadata,
+ pos: tF.length - 1,
+ });
+ } else {
+ tF = [
+ { fileName: currentFileName, template: lT, metadata: metadata, pos: 0 },
+ ];
+ }
+ storeData("templateFiles", tF);
+ activeState.fileName = currentFileName;
+ return currentFileName;
+}
+
+function obfuscate(data, mode = true) {
+ if (data == null | data == "") return "";
+ if (mode) {
+ return XORCipher.encode(sha256(passwordHash), data);
+ } else {
+ return XORCipher.decode(sha256(passwordHash), data);
+ }
+}
+
+function popFromTemplateFiles(fileName) {
+ let tF = retrieveData("templateFiles");
+ let newArray = [];
+ for (let obj of tF) {
+ if (obj.fileName != fileName) {
+ newArray.push(obj);
+ }
+ }
+ storeData("templateFiles", newArray);
+}
+
+function createBookShelf() {
+ let tF = retrieveData("templateFiles");
+ let bookShelf = {};
+ let date = getCurrentDate();
+ let saveFileName = date.current_time + "_" + date.current_date;
+
+ if (tF != null) {
+ bookShelf[0] = { name: "hash", data: activeState.userId, ts: saveFileName };
+ let i = 1;
+ for (let tFi of tF) {
+ let data = retrieveData(tFi.fileName, tFi.template);
+ bookShelf[i] = {};
+ bookShelf[i].name = tFi.fileName + "_m21_" + tFi.template;
+ if (activeState.settings.localOnly == "true") {
+ bookShelf[i].data = data;
+ } else {
+ bookShelf[i].data = obfuscate(data);
+ }
+
+ i++;
+ }
+ }
+ return bookShelf;
+}
+
+function importBookShelf() {
+ localStorage.clear();
+ var xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ if (this.responseText == "none") {
+ console.log("no files saved on server");
+ } else {
+ let respText = decodeURIComponent(this.responseText);
+ let mainArray = JSON.parse(respText);
+ let templateFilesArray = [];
+ for (let file of mainArray) {
+ if (file.name == "hash") continue;
+ store.setItem(sha256(file.name), file.data);
+ templateFilesArray.push({
+ fileName: file.name.split("_m21_")[0],
+ template: file.name.split("_m21_")[1],
+ });
+ }
+ store.setItem(
+ sha256("templateFiles_m21_"+activeState.userId),
+ obfuscate(JSON.stringify(templateFilesArray))
+ );
+ }
+ }
+ };
+ xhttp.open("GET", "php/?getStoredFiles=" + activeState.userId, true);
+ xhttp.setRequestHeader(
+ "Content-type",
+ "application/x-www-form-urlencoded; charset=UTF-8"
+ );
+ xhttp.send();
+}
+
+function storeSettings(data, get = false) {
+ let key = sha256("settings_m21_"+activeState.userId);
+
+ if (get) {
+ let cdata = "";
+ if (data == "getInit") {activeState.settings.persistentStorage = "true"}
+ try {
+ cdata = JSON.parse(obfuscate(store.getItem(key), false));
+ } catch (e) {
+ cdata = "";
+ }
+ if (data == "getInit") {activeState.settings.persistentStorage = "false"};
+ return cdata;
+ } else {
+ store.setItem(key, obfuscate(JSON.stringify(data)));
+ }
+}
+
+function clearStorage() {
+ store.clear();
+}
+
+export {
+ createStorageObj,
+ storeData,
+ retrieveData,
+ clearData,
+ getFileName,
+ createBookShelf,
+ importBookShelf,
+ storeSettings,
+ clearStorage
+};
diff --git a/js/2.0.1-alt/web.js b/js/2.0.1-alt/web.js
new file mode 100644
index 0000000..a3491df
--- /dev/null
+++ b/js/2.0.1-alt/web.js
@@ -0,0 +1,361 @@
+import buildForm from "./form.js";
+import { loadFileDivCallBack } from "./files.js";
+import { retrieveData, clearData, getFileName } from "./storage.js";
+import { insertTextBlocks, modalNotifier, resetNavBar } from "./evts.js";
+import { createTemplate, createTemplateCallBack} from "./createTemplate.js";
+import { logout, passwordHash } from "./scripts.js";
+import buildSettings from "./settings.js";
+
+
+function loadTemplate(template, newFlag = false, loadOnly = false) {
+ document.getElementById("siteTitle").innerHTML = template.replace(/_/g, " ");
+ activeState.loadedTemplate = template;
+
+ if (newFlag) {
+ activeState.fileName = "none";
+ } else {
+ activeState.fileName = getFileName();
+ }
+
+ document.getElementById("navMob").className = document
+ .getElementById("navMob")
+ .className.replace(" w3-show", "");
+
+ if (screen.width < 993) {
+ let sidebar = document.getElementById("sidebar");
+ sidebar.style.display = "none";
+ document.getElementById("siteTitle").innerHTML = "TG";
+ document.getElementById("logo").innerHTML = "TG";
+ }
+ var xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ let respText = decodeURIComponent(this.responseText);
+ if (loadOnly == "createTemplate") {
+ createTemplateCallBack(template, respText.split("!JSON_placeholder:")[0]);
+ return;
+ }
+ buildForm(respText, loadOnly);
+ if (loadOnly) {
+ loadFileDivCallBack();
+ return;
+ }
+
+ //retrieve previos userData / or preset data if newFile is called
+ let cdata;
+ if (newFlag) {
+ cdata = retrieveData("templatePreset", template);
+ } else {
+ cdata = retrieveData("userInputForce");
+ }
+ if (cdata != "") {
+ if (cdata != null) {
+ retrieveForm(cdata);
+ }
+ }
+
+ //select first object and focus on it
+ let obj = activeState.templateObjectsPurified;
+ let firstElement = document.getElementById(obj[0].word.replace(/ /g, "_"));
+ if (firstElement != null) firstElement.focus();
+
+ }
+ };
+ xhttp.open("GET", "php/?template=" + template, true);
+ xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
+ xhttp.send();
+}
+
+function loadNewTemplate(template) {
+
+ //reset navbar above all else
+ resetNavBar();
+
+ //sessionVerfication check
+ if (!passwordHash.verify()) {
+ modalNotifier("Error: Session is not authenticated...", 0, false);
+ }
+
+ //set current page value in activeState object
+ activeState.activePage = "template";
+
+ let sidebarDiv = document.getElementById("sidebar");
+ sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
+
+ clearData("userInput", template);
+ loadTemplate(template, true);
+}
+
+function loadNavBar() {
+ var xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ let res = "";
+ try {
+ res = JSON.parse(this.responseText);
+ } catch (e) {
+ console.log("error", this.responseText);
+ return;
+ }
+
+ let divMob = document.getElementById("navMob");
+ for (let x in res) {
+ let aMob = document.createElement("a");
+
+ aMob.setAttribute("href", "javascript:void(0)");
+ aMob.setAttribute("data-template", res[x][1]);
+ aMob.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
+ aMob.innerHTML = res[x][0];
+
+ divMob.appendChild(aMob);
+
+ activeState.templates.push(res[x][1]);
+ }
+ let createEntry = document.createElement("a");
+ createEntry.setAttribute("href", "javascript:void(0)");
+ createEntry.setAttribute("data-template", "!createNew");
+ createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
+ createEntry.style.borderTop = "2px solid rgb(221, 221, 221)";
+ createEntry.innerHTML = "Manage templates";
+ divMob.appendChild(createEntry);
+
+ createEntry = document.createElement("a");
+ createEntry.setAttribute("href", "javascript:void(0)");
+ createEntry.setAttribute("data-template", "!settings");
+ createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
+ createEntry.innerHTML = "Settings";
+ divMob.appendChild(createEntry);
+
+ createEntry = document.createElement("a");
+ createEntry.setAttribute("href", "javascript:void(0)");
+ createEntry.setAttribute("data-template", "!logout");
+ createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large", "w3-flat-pomegranate");
+ createEntry.innerHTML = "Logout";
+ divMob.appendChild(createEntry);
+
+ divMob.addEventListener("click", (e) => {
+ e.preventDefault;
+ if (e.target && e.target.matches("a.w3-bar-item")) {
+ let template = e.target.dataset.template;
+ if (template == "!createNew") {
+ createTemplate();
+ return;
+ }
+ if (template == "!logout") {
+ logout();
+ return;
+ }
+ if (template == "!settings") {
+ buildSettings();
+ return;
+ }
+ loadNewTemplate(template);
+ }
+ });
+ }
+ };
+ xhttp.open("GET", "php/?templates", true);
+ xhttp.send();
+}
+function initTextBlocks() {
+ var xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ let res = "";
+ try {
+ res = JSON.parse(this.responseText);
+ } catch (e) {
+ console.log("error", this.responseText)
+ return;
+ }
+ const textBlocksHolder = document.getElementById("textBlocks");
+ const divReg = document.getElementById("navTb");
+ for (let x in res) {
+ if (res[x][1].length < 1) continue;
+
+ let aReg = document.createElement("a");
+ aReg.setAttribute("href", "javascript:void(0)");
+ aReg.classList.add("w3-bar-item", "w3-hide-small", "w3-padding-small");
+ let textBlockText = res[x][1];
+ if (res[x][1].length > 80) {
+ textBlockText = res[x][1].substr(0, 80) + "...";
+ }
+ aReg.innerHTML = "" + res[x][0] + ": " + textBlockText;
+ divReg.appendChild(aReg);
+
+ const text = document.createTextNode(
+ res[x][0] + ": " + res[x][1] + "\n"
+ );
+ textBlocksHolder.appendChild(text);
+ }
+ divReg.addEventListener("click", (e) => {
+ if (e.target && e.target.matches("a.w3-bar-item")) {
+ insertTextBlocks(e.target);
+ }
+ });
+ }
+ };
+ xhttp.open("GET", "php/?textBlocks", true);
+ xhttp.send();
+}
+
+function setTemplatePreset(template, formData) {
+ //console.log(template +" : "+ formData);
+ var xhttp = new XMLHttpRequest();
+ xhttp.open("POST", "php/?setForm");
+ xhttp.setRequestHeader("Accept", "application/json");
+ xhttp.setRequestHeader("Content-Type", "application/json");
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ //console.log(this.responseText);
+ }
+ };
+ let data = {
+ template: template,
+ data: formData,
+ };
+
+ xhttp.send(JSON.stringify(data));
+}
+
+function setNewTemplate(fileName, data) {
+ let obj = {
+ fileName: fileName,
+ data: data,
+ };
+ //console.log(template +" : "+ formData);
+ var xhttp = new XMLHttpRequest();
+ xhttp.open("POST", "php/?setTemplate");
+ xhttp.setRequestHeader("Accept", "application/json");
+ xhttp.setRequestHeader("Content-Type", "application/json");
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ //console.log(this.responseText);
+ }
+ };
+
+ xhttp.send(JSON.stringify(obj));
+}
+
+function storeFilesToServer(data) {
+ //console.log(template +" : "+ formData);
+ var xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ if (this.responseText == "success") {
+ console.log("files saved");
+ }
+ }
+ };
+ xhttp.open("POST", "php/?storeFiles", true);
+ xhttp.setRequestHeader("Accept", "application/json");
+ xhttp.setRequestHeader("Content-Type", "application/json");
+ xhttp.send(JSON.stringify(data));
+}
+
+function checkForStoredDataOnServer() {
+ var xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ if (this.responseText == "none") {
+ } else {
+ activeState.serverFilesTs = this.responseText;
+ let btn = document.getElementById("importModalBtn");
+ btn.style.display = "";
+ }
+ }
+ };
+ xhttp.open("GET", "php/?storedFiles="+activeState.userId, true);
+ xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
+ xhttp.send();
+}
+
+function delStoredDataOnServer() {
+ var xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ if (this.responseText == "none") {
+ let btn = document.getElementById("importModalBtn");
+ btn.style.display = "none";
+ }
+ }
+ };
+ xhttp.open("GET", "php/?storedFiles="+activeState.userId+"&del", true);
+ xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
+ xhttp.send();
+}
+
+
+function retrieveForm(arr) {
+
+ for (let i = 0; i < arr.length; i++) {
+
+ let e = document.getElementById(arr[i].name);
+ if (e === null) {
+ //parse connected list
+ let id = arr[i].name.split("cl-")[1];
+ //escape cl-text:!ls
+ if (id != undefined) id = id.split(":")[0];
+ e = document.getElementById(id);
+ if (e === null) {
+ //parse connected list main
+ let id = arr[i].name.split("clM-")[1];
+ e = document.getElementById(id);
+ if (e === null) continue;
+ }
+
+ }
+ //handle connected list Main item button or list
+ if (e.name.substr(0, 4) == "clM-") {
+ if (arr[i].value != "!none") {
+ let clElement = document.getElementById(e.dataset.word);
+ if (clElement === null) {
+ clElement = document.getElementById(arr[i].value.replace(/ /g, "_"));
+ }
+ //make shure it is visible if selected before
+ if (clElement != undefined) clElement.parentElement.parentElement.classList.remove("hidden");
+ e.value = arr[i].value;
+ }
+
+ continue;
+ }
+
+ switch (e.nodeName) {
+ case "TEXTAREA":
+ if (e.parentElement != undefined) {
+ if (e.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
+ e.innerHTML = arr[i].value;
+ e = e.parentElement.getElementsByClassName("pell-content")[0];
+ }
+ }
+ e.innerHTML = arr[i].value;
+ break;
+ case "INPUT":
+ e.value = arr[i].value;
+ break;
+ case "SELECT":
+ for (let j = 0; j < e.options.length; j++) {
+ if (e.options[j].value == arr[i].value) {
+ // Item is found. Set its property and exit
+ e.options[j].selected = true;
+ break;
+ }
+ }
+ break;
+ default:
+ e.innerHTML = arr[i].value;
+ break;
+ }
+ }
+}
+export {
+ loadTemplate,
+ loadNavBar,
+ initTextBlocks,
+ loadNewTemplate,
+ setTemplatePreset,
+ setNewTemplate,
+ storeFilesToServer,
+ checkForStoredDataOnServer,
+ delStoredDataOnServer
+};
diff --git a/js/2.0.1-alt/xorc.js b/js/2.0.1-alt/xorc.js
new file mode 100644
index 0000000..86d82b5
--- /dev/null
+++ b/js/2.0.1-alt/xorc.js
@@ -0,0 +1,187 @@
+
+const XORCipher = {
+ encode: function (key, data, seed) {
+ data = xor_encrypt(key, data, seed);
+ return b64_encode(data);
+ },
+ decode: function (key, data) {
+ data = b64_decode(data);
+ return xor_decrypt(key, data);
+ },
+ seed: function (n) {
+ return randString(n);
+ },
+};
+
+function stringToUtf8ByteArray(str) {
+ var out = [],
+ p = 0;
+ for (var i = 0; i < str.length; i++) {
+ var c = str.charCodeAt(i);
+ if (c < 128) {
+ out[p++] = c;
+ } else if (c < 2048) {
+ out[p++] = (c >> 6) | 192;
+ out[p++] = (c & 63) | 128;
+ } else if (
+ (c & 0xfc00) == 0xd800 &&
+ i + 1 < str.length &&
+ (str.charCodeAt(i + 1) & 0xfc00) == 0xdc00
+ ) {
+ // Surrogate Pair
+ c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
+ out[p++] = (c >> 18) | 240;
+ out[p++] = ((c >> 12) & 63) | 128;
+ out[p++] = ((c >> 6) & 63) | 128;
+ out[p++] = (c & 63) | 128;
+ } else {
+ out[p++] = (c >> 12) | 224;
+ out[p++] = ((c >> 6) & 63) | 128;
+ out[p++] = (c & 63) | 128;
+ }
+ }
+ return out;
+}
+
+function utf8ByteArrayToString(bytes) {
+ // array of bytes
+ var out = [],
+ pos = 0,
+ c = 0;
+ while (pos < bytes.length) {
+ var c1 = bytes[pos++];
+ if (c1 < 128) {
+ out[c++] = String.fromCharCode(c1);
+ } else if (c1 > 191 && c1 < 224) {
+ var c2 = bytes[pos++];
+ out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
+ } else if (c1 > 239 && c1 < 365) {
+ // Surrogate Pair
+ var c2 = bytes[pos++];
+ var c3 = bytes[pos++];
+ var c4 = bytes[pos++];
+ var u =
+ (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
+ 0x10000;
+ out[c++] = String.fromCharCode(0xd800 + (u >> 10));
+ out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
+ } else {
+ var c2 = bytes[pos++];
+ var c3 = bytes[pos++];
+ out[c++] = String.fromCharCode(
+ ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
+ );
+ }
+ }
+ return out.join("");
+}
+
+var b64_table =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+function b64_encode(data) {
+ var o1,
+ o2,
+ o3,
+ h1,
+ h2,
+ h3,
+ h4,
+ bits,
+ r,
+ i = 0,
+ enc = "";
+ if (!data) {
+ return data;
+ }
+ do {
+ o1 = data[i++];
+ o2 = data[i++];
+ o3 = data[i++];
+ bits = (o1 << 16) | (o2 << 8) | o3;
+ h1 = (bits >> 18) & 0x3f;
+ h2 = (bits >> 12) & 0x3f;
+ h3 = (bits >> 6) & 0x3f;
+ h4 = bits & 0x3f;
+ enc +=
+ b64_table.charAt(h1) +
+ b64_table.charAt(h2) +
+ b64_table.charAt(h3) +
+ b64_table.charAt(h4);
+ } while (i < data.length);
+ r = data.length % 3;
+ return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
+}
+
+function b64_decode(data) {
+ var o1,
+ o2,
+ o3,
+ h1,
+ h2,
+ h3,
+ h4,
+ bits,
+ i = 0,
+ result = [];
+ if (!data) {
+ return data;
+ }
+ data += "";
+ do {
+ h1 = b64_table.indexOf(data.charAt(i++));
+ h2 = b64_table.indexOf(data.charAt(i++));
+ h3 = b64_table.indexOf(data.charAt(i++));
+ h4 = b64_table.indexOf(data.charAt(i++));
+ bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4;
+ o1 = (bits >> 16) & 0xff;
+ o2 = (bits >> 8) & 0xff;
+ o3 = bits & 0xff;
+ result.push(o1);
+ if (h3 !== 64) {
+ result.push(o2);
+ if (h4 !== 64) {
+ result.push(o3);
+ }
+ }
+ } while (i < data.length);
+ return result;
+}
+
+function rand(min, max) {
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+}
+
+function randString(n) {
+ var r = "";
+ for (var i = 0; i < n; i++) r += String.fromCharCode(rand(1, 65535));
+
+ return r;
+}
+
+function xor_encrypt(key, data, seed) {
+ if (typeof seed == "undefined") seed = randString(32);
+
+ var d = stringToUtf8ByteArray(seed + String.fromCharCode(0) + data),
+ k = stringToUtf8ByteArray(key),
+ r = [];
+
+ for (var i = 0; i < d.length; i++)
+ r[i] = r[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
+
+ return r;
+}
+
+function xor_decrypt(key, data) {
+ var d = data,
+ k = stringToUtf8ByteArray(key),
+ r = [];
+
+ for (var i = 0; i < d.length; i++)
+ r[i] = d[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
+
+ r.splice(0, r.indexOf(0) + 1);
+ return utf8ByteArrayToString(r);
+}
+
+ export default XORCipher;
\ No newline at end of file