diff options
Diffstat (limited to 'static/js/forms.ts')
-rw-r--r-- | static/js/forms.ts | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/static/js/forms.ts b/static/js/forms.ts new file mode 100644 index 0000000..263fda1 --- /dev/null +++ b/static/js/forms.ts @@ -0,0 +1,130 @@ +(function () { + + const cookiesDisabled = !navigator.cookieEnabled; + + if (cookiesDisabled) { + document.cookie = "disabled"; + document.cookie.indexOf("disabled"); + return console.warn("WARNING: Cannot persist form state due to cookie restrictions"); + } + + const storage = document.createEvent("Event"); + storage.initEvent("storage", true, true); + + ["pageshow", "URLChangedCustomEvent", "DOMContentLoaded"].forEach(function (event) { + self.addEventListener(event, function (event) { + const input = Array.prototype.slice.call(document.querySelectorAll("form input")); + const select = Array.prototype.slice.call(document.querySelectorAll("form select")); + const textarea = Array.prototype.slice.call(document.querySelectorAll("form textarea")); + const summary = Array.prototype.slice.call(document.querySelectorAll("details summary")); + + const states = input.concat(select).concat(textarea); + + for (var i = 0; i < states.length; i++) { + const state = states[i]; + const sync = i === states.length - 1; + + if (localStorage[state.id]) { + if (state.type === "radio" || state.type === "checkbox") { + if (localStorage[state.id] === "on") state.checked = true; + } else state.value = localStorage[state.id]; + } + + if (sync) self.dispatchEvent(storage); + + state.addEventListener("change", function (event) { + + // console.log("INFO: STATE:", event.target); + // console.log("INFO: ID:", event.target.id); + // console.log("INFO: NAME:", event.target.name); + // console.log("INFO: TYPE:", event.target.type); + // console.log("INFO: VALUE:", event.target.value); + // console.log("INFO: CHECKED:", event.target.checked); + + localStorage[event.target.id] = event.target.value; + + const group = document.querySelectorAll("input[name='".concat(event.target.name, "']")); + + for (var j = 0; j < group.length; j++) { + const member = group[j]; + if ((member.type === "radio" || member.type === "checkbox") && !member.checked) { + localStorage[member.id] = "off"; + } + } + self.dispatchEvent(new Event("storage")); + }); + } + + for (var k = 0; k < summary.length; k++) { + let child = summary[k]; + let details = child.parentElement; + + if (details.id && details.nodeName === "DETAILS") { + sessionStorage[details.id] === "false" && details.removeAttribute("open"); + sessionStorage[details.id] === "true" && details.setAttribute("open", true); + + child.addEventListener("click", function (event) { + let child = (event.target.nodeName === "SUMMARY" && event.target) + || event.target.parentElement; + let details = child.parentElement; + if (details.id && details.nodeName === "DETAILS") { + sessionStorage[details.id] = !details.open; + } + }); + } + } + }); + }); + + ["storage"].forEach(function (event) { + self.addEventListener(event, function () { + let stylesheet; + + stylesheet = document.querySelector('link[href$="default-simple.css"]') + + if (localStorage["config.layout.simple"] === "on") stylesheet.rel = "stylesheet" + if (localStorage["config.layout.default"] === "on") stylesheet.rel = "alternate stylesheet" + + stylesheet = document.querySelector('link[href$="default-fast.css"]') + + if (localStorage["config.navigation.fast"] === "on") stylesheet.rel = "stylesheet" + if (localStorage["config.navigation.slow"] === "on") stylesheet.rel = "alternate stylesheet" + + for (var i = 0; i < document.styleSheets.length; i++) { + let stylesheet = document.styleSheets[i]; + for (var k = 0; k < stylesheet.rules.length; k++) { + let media = stylesheet.rules[k].media; + if (media && media.mediaText.includes("prefers-color-scheme")) { + if (localStorage["config.theme.light"] === "on") { + media.mediaText = "(prefers-color-scheme: dark)"; + if (getComputedStyle(document.body).getPropertyValue("color-scheme") === "dark") { media.mediaText = "(prefers-color-scheme: light)"; } + } + + if (localStorage["config.theme.auto"] === "on") { + media.mediaText = "(prefers-color-scheme: dark)"; + } + + if (localStorage["config.theme.dark"] === "on") { + media.mediaText = "(prefers-color-scheme: light)"; + if (getComputedStyle(document.body).getPropertyValue("color-scheme") === "light") { media.mediaText = "(prefers-color-scheme: dark)"; } + } + } + } + } + }); + }); + + const early = setInterval(persistence, 4); + + function persistence() { + if (document.styleSheets.length > 0) { + self.dispatchEvent(storage); + clearInterval(early); + } + } + + self.addEventListener("DOMContentLoaded", function () { + self.dispatchEvent(storage); + clearInterval(early); + }); +})(); |