123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- // Get an element by id or an Element object
- function getelem(id) {
- return (id instanceof Element) ? id : document.getElementById(id);
- }
- // Read a key=value text file and return it as a Promise of a Map
- function fetchconfig(url) {
- var xdr = new XMLHttpRequest();
- return fetch(url, {cache: "no-store"})
- .then(res => {
- if (!res.ok) {
- throw new Error("HTTP error "+response.status);
- } else {
- return res.text();
- }
- })
- .then(text => {
- var map = new Map();
- for (const c of text.split(/[\r\n]+/)) {
- var m = c.match(/^\s*("(?:[^"]|"")*"|[^"]+)\s*=(.*)$/);
- if (m) {
- var k = m[1].replaceAll(/(^"|"$|(")")/g, "$2");
- map.set(k, m[2]);
- }
- }
- return map;
- });
- }
- // Initialize a form from a map
- function initform(form,map) {
- var button = null;
- var clearers = new Map;
- form = getelem(form);
- for (var field of form.elements) {
- if (field instanceof HTMLInputElement &&
- !field.classList.contains("noload")) {
- var val = map.get(field.name);
- if (val == undefined)
- val = '';
- if (field.type == 'checkbox') {
- const checked = !val.match(/^(0*|[fn].*|of.*)$/i);
- field.checked = checked;
- if (checked) {
- const clearer_name = '-' + field.name;
- if (!clearers.has(clearer_name)) {
- clearers.set(clearer_name, 1);
- }
- }
- } else if (field.type == 'radio') {
- field.checked = (val == field.name);
- } else if (field.type == 'hidden') {
- clearers.set(field.name, 0);
- } else {
- field.value = val;
- }
- } else if (field instanceof HTMLButtonElement &&
- field.type == 'submit') {
- button = field;
- }
- }
- for (const [what, need] of clearers) {
- if (need) {
- var clearer = document.createElement('INPUT');
- clearer.type = 'hidden';
- clearer.name = what;
- form.prepend(clearer);
- }
- }
- if (button) {
- button.disabled = false; // All loaded, enable the submit button
- }
- }
- // Load form initialization data
- function loadform(form, url) {
- fetchconfig(url)
- .then(map => { initform(form, map) })
- .catch(() => {});
- }
- // Replace HTML element contents with the contents of a map
- function fillin(map,html)
- {
- for (const [key,val] of map) {
- var e = document.getElementById(key);
- if (e) {
- if (html)
- e.innerHTML = val;
- else
- e.innerText = val;
- }
- }
- }
- // Load status or HTML data
- function load(url,html)
- {
- fetchconfig(url)
- .then(map => { initdata(map,map) })
- .catch(() => {});
- }
- // POST file upload with progress and response text
- function uploadfile(event) {
- event.preventDefault();
- var form = event.currentTarget;
- var elem = form.elements;
- var files = elem["file"].files;
- if (files.length != 1) {
- /* Show error */
- return;
- }
- var file = files[0];
- var xhr = new XMLHttpRequest();
- var progress = form.querySelector("progress");
- if (progress != undefined) {
- progress.value = 0;
- xhr.upload.addEventListener("progress", (event) => {
- if (event.lengthComputable) {
- progress.max = event.total;
- progress.value = event.loaded;
- }
- });
- }
- var result = form.querySelector("pre.result");
- if (result != undefined) {
- result.className = "result hide";
- }
- xhr.addEventListener("loadend", (event) => {
- const ok = xhr.status >= 200 && xhr.status <= 299;
- if (progress != undefined) {
- progress.value = ok ? progress.max : 0;
- }
- if (result != undefined) {
- result.className = "result " + (ok ? "ok" : "err");
- result.innerText = xhr.responseText;
- }
- });
- xhr.open("POST", form.action);
- xhr.responseType = 'text';
- xhr.send(file);
- }
- // Enable a button (this ensures that the necessary scripts have been
- // run before one can submit)
- function enablebutton(id,on) {
- getelem(id).disabled = !on;
- }
- // Flip the status of an INPUT element between text and password
- function showpwd(id,me) {
- var pwd = getelem(id);
- const now_visible = me.classList.toggle('hide');
- me.classList.toggle('show',!now_visible);
- const new_type = now_visible ? 'text' : 'password';
- pwd.setAttribute('type', new_type);
- }
- // Hack to include an HTML files. Sadly, does not support
- // including files with <script> tags.
- function inc(url) {
- var me = document.currentScript;
- fetch(url)
- .then((response) => response.text())
- .then((text) => { me.outerHTML = text; });
- }
|