"use strict";
window.addEventListener("DOMContentLoaded", function() {
const SUPPORTED_TYPES = ["Files", "application/x-moz-file"];
let body = document.getElementsByTagName("body")[0];
let file_upload_text = null;
let remaining_files = 0;
let url = document.location.pathname;
if(!url.endsWith("/"))
url += "/";
body.addEventListener("dragover", function(ev) {
if(SUPPORTED_TYPES.find(function(el) {
return (ev.dataTransfer.types.contains || ev.dataTransfer.types.includes).call(ev.dataTransfer.types, el);
}))
ev.preventDefault();
});
body.addEventListener("drop", function(ev) {
if(SUPPORTED_TYPES.find(function(el) {
return (ev.dataTransfer.types.contains || ev.dataTransfer.types.includes).call(ev.dataTransfer.types, el);
})) {
ev.preventDefault();
process_transfer(ev.dataTransfer);
}
});
body.addEventListener("paste", function(ev) {
if(ev.target.tagName != "INPUT" && (ev.clipboardData || window.clipboardData).files.length) {
ev.preventDefault();
process_transfer(ev.clipboardData || window.clipboardData);
}
});
function process_transfer(transfer) {
for(let i = transfer.files.length - 1; i >= 0; --i) {
if(!transfer.items[i].webkitGetAsEntry) {
let file = transfer.files[i];
upload_file(url + encodeURIComponent(file.name), file);
} else
recurse_upload(transfer.items[i].webkitGetAsEntry(), url);
}
}
let file_upload = document.querySelector("input[type=file]");
let upload_list = document.createElement("dl");
file_upload.parentElement.appendChild(upload_list);
file_upload.addEventListener("change", function() {
for(let i = file_upload.files.length - 1; i >= 0; --i) {
let file = file_upload.files[i];
upload_file(url + encodeURIComponent(file.name), file);
}
});
function upload_file(req_url, file) {
++remaining_files;
let filename_line = document.createElement("dt");
filename_line.innerText = file.name;
upload_list.appendChild(filename_line)
let progress_progress_label = document.createElement("label");
let progress_progress_desc = document.createElement("span");
let progress_progress = document.createElement("progress");
progress_progress.value = 0;
progress_progress_label.appendChild(progress_progress);
progress_progress_label.appendChild(document.createTextNode(" "));
progress_progress_desc.innerText = "pending";
progress_progress_label.appendChild(progress_progress_desc);
let progress_speed = document.createElement("span");
let progress_speed_text = document.createTextNode("?");
progress_speed.appendChild(progress_speed_text);
progress_speed.appendChild(document.createTextNode("/s"));
let progress_time = document.createElement("span");
progress_speed.appendChild(progress_time);
let progress_line = document.createElement("dd");
progress_line.appendChild(progress_progress_label);
progress_line.appendChild(document.createTextNode(" "));
progress_line.appendChild(progress_speed);
progress_line.appendChild(document.createTextNode(" "));
progress_line.appendChild(progress_time);
upload_list.appendChild(progress_line)
if(!file_upload_text) {
file_upload_text = document.createTextNode(1);
file_upload.parentNode.insertBefore(file_upload_text, file_upload.nextSibling); } else
file_upload_text.data = remaining_files;
let request = new XMLHttpRequest();
request.addEventListener("loadend", function(e) {
if(request.status >= 200 && request.status < 300) {
if(!--remaining_files)
window.location.reload();
filename_line.remove();
progress_line.remove();
file_upload_text.data = remaining_files;
} else {
progress_line.innerText = request.response;
file_upload.outerHTML = req_url + "<br />" + request.response;
}
});
let start = 0;
let update = -1000;
request.upload.addEventListener("loadstart", function(e) {
start = e.timeStamp;
});
let prog = function(e) {
if(e.lengthComputable) {
progress_progress.value = event.loaded;
progress_progress.max = event.total;
let elapsed = (e.timeStamp - start) / 1000; if(elapsed > 0.1) {
let speed = event.loaded / elapsed;
progress_progress_desc.innerText = human_readable_size(event.loaded) + "/" + human_readable_size(event.total);
progress_speed_text.data = human_readable_size(speed);
progress_time.innerText = hms(elapsed) + "/" + hms(event.total / speed);
}
} else {
progress_progress.removeAttribute("value");
progress_progress_desc.innerText = "uploading";
request.upload.removeEventListener("progress", prog);
}
};
request.upload.addEventListener("progress", prog);
request.open("PUT", req_url);
if(file.lastModified)
request.setRequestHeader("X-Last-Modified", file.lastModified);
request.send(file);
}
function recurse_upload(entry, base_url) {
if(entry.isFile) {
if(entry.file)
entry.file(function(f) {
upload_file(base_url + entry.fullPath.split("/").filter(function(seg) { return seg; }).map(encodeURIComponent).join("/"), f);
});
else
upload_file(base_url + entry.fullPath.split("/").filter(function(seg) { return seg; }).map(encodeURIComponent).join("/"), entry.getFile());
} else all_in_reader(entry.createReader(), function(f) {
recurse_upload(f, base_url)
});
}
function all_in_reader(reader, f) {
reader.readEntries(function(e) {
e.forEach(f);
if(e.length)
all_in_reader(reader, f);
});
}
const LN_KIB = Math.LN2 * 10; function human_readable_size(num) {
let exp = Math.min(Math.max(Math.trunc(Math.log(num) / LN_KIB), 0), 8);
let val = num / Math.pow(2, exp * 10);
return ((exp > 0) ? Math.round(val * 10) / 10 : Math.round(val)) + " "
+ ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"][Math.trunc(Math.max(exp, 0))];
}
function hms(seconds) {
let h = Math.trunc(seconds / 3600);
let m = Math.trunc((seconds % 3600) / 60);
let s = Math.trunc(seconds % 60);
if(h)
return h + ":" + String(m).padStart(2, '0') + ":" + String(s).padStart(2, '0');
else if(m)
return m + ":" + String(s).padStart(2, '0');
else
return seconds.toFixed(1) + "s";
}
});