Add upload to navbar
This commit is contained in:
+16
-26
@@ -1,11 +1,11 @@
|
||||
// Progressive enhancement for the upload form. With JavaScript off the plain
|
||||
// multipart POST still works; everything here is additive.
|
||||
// Everything here is additive: with JavaScript off, the plain multipart POST
|
||||
// still works.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
// Copy buttons appear on the server-rendered result page too, which has no
|
||||
// upload form, so they are wired before anything form-specific bails out.
|
||||
// They ship hidden so that without this script there is no dead button.
|
||||
// Wired before the form-specific code bails out, because the result page has
|
||||
// copy buttons and no form. They ship hidden, so without this there is no
|
||||
// dead button.
|
||||
function wireCopy() {
|
||||
var buttons = document.querySelectorAll('button.copy[data-copy]');
|
||||
Array.prototype.forEach.call(buttons, function (button) {
|
||||
@@ -20,12 +20,9 @@
|
||||
timer = setTimeout(function () { button.textContent = label; }, 1500);
|
||||
}
|
||||
|
||||
// Copying the selection needs neither a permission nor a secure context,
|
||||
// so it answers for both of the ways the clipboard API can let us down:
|
||||
// missing entirely (this service is reached over plain HTTP as well as
|
||||
// HTTPS, and the API exists only on the secure side) or present and
|
||||
// refusing (an unfocused document, a permissions policy). If even that
|
||||
// fails, the text is selected either way, so say what to press.
|
||||
// Answers both ways the clipboard API fails us: absent over plain HTTP,
|
||||
// where it is not a secure context, and present but refusing. Needs no
|
||||
// permission. If it fails too, the text is selected, so say what to press.
|
||||
function copySelection() {
|
||||
var ok = false;
|
||||
try { ok = document.execCommand('copy'); } catch (e) { /* ok stays false */ }
|
||||
@@ -47,8 +44,6 @@
|
||||
}
|
||||
wireCopy();
|
||||
|
||||
// Destructive buttons ask first. The attribute carries the question, so the
|
||||
// markup decides what is worth confirming and this stays generic.
|
||||
Array.prototype.forEach.call(document.querySelectorAll('[data-confirm]'), function (button) {
|
||||
button.addEventListener('click', function (e) {
|
||||
if (!window.confirm(button.dataset.confirm)) e.preventDefault();
|
||||
@@ -67,8 +62,7 @@
|
||||
var submit = document.getElementById('submit');
|
||||
var errorBox = document.getElementById('error');
|
||||
|
||||
// The session's limits are rendered by the server, so this script never has
|
||||
// to ask who the visitor is. Zero means unlimited.
|
||||
// Zero means unlimited.
|
||||
var maxSize = parseInt(form.dataset.maxSize, 10) || 0;
|
||||
|
||||
function formatSize(n) {
|
||||
@@ -82,7 +76,6 @@
|
||||
errorBox.hidden = !msg;
|
||||
}
|
||||
|
||||
// --- drag and drop ------------------------------------------------------
|
||||
function describeSelection() {
|
||||
var f = fileInput.files[0];
|
||||
dropHint.textContent = f ? f.name + ' - ' + formatSize(f.size)
|
||||
@@ -109,7 +102,6 @@
|
||||
});
|
||||
fileInput.addEventListener('change', describeSelection);
|
||||
|
||||
// --- upload -------------------------------------------------------------
|
||||
form.addEventListener('submit', function (e) {
|
||||
var file = fileInput.files[0];
|
||||
if (!file) return; // let the browser's own validation speak
|
||||
@@ -127,16 +119,15 @@
|
||||
progress.hidden = false;
|
||||
|
||||
// FormData follows markup order, not painted order, so the options and the
|
||||
// token precede the file part exactly as the server requires. The drop
|
||||
// zone only looks like it comes first; see the order rules in style.css.
|
||||
// token precede the file part as the server requires. The drop zone only
|
||||
// looks like it comes first; see the order rules in style.css.
|
||||
var data = new FormData(form);
|
||||
var started = Date.now();
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', form.action);
|
||||
// Ask for the page a plain form post would have been given. What a
|
||||
// finished upload looks like is the server's business, and it already
|
||||
// renders it; this script only adds the progress bar on the way there.
|
||||
// Ask for the page a plain form post would get: the server owns what a
|
||||
// finished upload looks like, and this only adds a progress bar.
|
||||
xhr.setRequestHeader('Accept', 'text/html');
|
||||
|
||||
xhr.upload.onprogress = function (ev) {
|
||||
@@ -153,10 +144,9 @@
|
||||
};
|
||||
|
||||
xhr.onload = function () {
|
||||
// Whatever came back, the result page or an error page, is the page the
|
||||
// browser should be showing now. Writing it into this document rather
|
||||
// than navigating leaves the address on the form's own URL, so a reload
|
||||
// offers a fresh form instead of posting the file a second time.
|
||||
// Writing the response into this document rather than navigating leaves
|
||||
// the address on the form's URL, so a reload offers a fresh form instead
|
||||
// of posting the file again.
|
||||
document.open();
|
||||
document.write(xhr.responseText);
|
||||
document.close();
|
||||
|
||||
Reference in New Issue
Block a user